blimpy 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/blimpy.gemspec +1 -0
- data/features/cli/scp.feature +37 -0
- data/features/cli/ssh.feature +1 -1
- data/features/step_definitions/cli_steps.rb +6 -0
- data/lib/blimpy/box.rb +63 -10
- data/lib/blimpy/cli.rb +26 -9
- data/lib/blimpy/fleet.rb +1 -0
- data/lib/blimpy/livery.rb +33 -0
- data/lib/blimpy/version.rb +1 -1
- data/spec/blimpy/box_spec.rb +16 -0
- data/spec/blimpy/livery_spec.rb +19 -0
- metadata +22 -6
data/blimpy.gemspec
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
Feature: SCP a file into a named VM
|
2
|
+
In order to easily copy files from my local host to the named VM
|
3
|
+
As a Blimpy user
|
4
|
+
I should be able to run `blimpy scp <name> <file> [dest]`
|
5
|
+
|
6
|
+
Scenario: SCPing with an invalid blimp name
|
7
|
+
Given I have the Blimpfile:
|
8
|
+
"""
|
9
|
+
Blimpy.fleet do |f|
|
10
|
+
f.add do |host|
|
11
|
+
host.name = 'Cucumber Host'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
"""
|
15
|
+
And I have a file named "hello.txt"
|
16
|
+
When I run `blimpy scp Gherkins hello.txt`
|
17
|
+
Then the exit status should be 1
|
18
|
+
And the output should contain:
|
19
|
+
"""
|
20
|
+
Could not find a blimp named "Gherkins"
|
21
|
+
"""
|
22
|
+
|
23
|
+
# This test is in the same boat that the complimentary test in ssh.feature is
|
24
|
+
# in.
|
25
|
+
@slow @destroy @wip
|
26
|
+
Scenario: SCPing a valid file
|
27
|
+
Given I have the Blimpfile:
|
28
|
+
"""
|
29
|
+
Blimpy.fleet do |f|
|
30
|
+
f.add do |host|
|
31
|
+
host.name = 'Cucumber Host'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
"""
|
35
|
+
And I have a file named "hello.txt"
|
36
|
+
When I run `blimpy scp "Cucumber Host" hello.txt`
|
37
|
+
Then the exit status should be 0
|
data/features/cli/ssh.feature
CHANGED
@@ -26,6 +26,12 @@ Given /^I have a single VM running$/ do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
Given /^I have a file named "([^"]*)"$/ do |filename|
|
30
|
+
File.open(filename, 'w') do |fd|
|
31
|
+
fd.write("I am #{filename}\n")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
29
35
|
When /^I ssh into the machine$/ do
|
30
36
|
step %{I run `blimpy start`}
|
31
37
|
step %{I run `blimpy ssh "Cucumber Host" -o StrictHostKeyChecking=no` interactively}
|
data/lib/blimpy/box.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'blimpy/helpers/state'
|
2
|
+
require 'blimpy/livery'
|
2
3
|
require 'blimpy/keys'
|
3
4
|
|
4
5
|
module Blimpy
|
@@ -37,6 +38,8 @@ module Blimpy
|
|
37
38
|
@tags = {}
|
38
39
|
@server = server
|
39
40
|
@fleet_id = 0
|
41
|
+
@ssh_connected = false
|
42
|
+
@exec_commands = true
|
40
43
|
end
|
41
44
|
|
42
45
|
def region=(newRegion)
|
@@ -65,6 +68,14 @@ module Blimpy
|
|
65
68
|
write_state_file
|
66
69
|
end
|
67
70
|
|
71
|
+
def bootstrap
|
72
|
+
@exec_commands = false
|
73
|
+
unless livery.nil?
|
74
|
+
wait_for_sshd
|
75
|
+
bootstrap_livery
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
68
79
|
def stop
|
69
80
|
unless @server.nil?
|
70
81
|
@server.stop
|
@@ -91,7 +102,6 @@ module Blimpy
|
|
91
102
|
end
|
92
103
|
end
|
93
104
|
|
94
|
-
|
95
105
|
def state_file
|
96
106
|
if @server.nil?
|
97
107
|
raise Exception, "I can't make a state file without a @server!"
|
@@ -120,19 +130,62 @@ module Blimpy
|
|
120
130
|
'no name'
|
121
131
|
end
|
122
132
|
|
123
|
-
def
|
133
|
+
def run_command(*args)
|
134
|
+
if @exec_commands
|
135
|
+
::Kernel.exec(*args)
|
136
|
+
else
|
137
|
+
::Kernel.system(*args)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def ssh_into(*args)
|
142
|
+
# Support using #ssh_into within our own code as well to pass arguments
|
143
|
+
# to the ssh(1) binary
|
144
|
+
args = args || ARGV[2 .. -1]
|
145
|
+
run_command('ssh', '-o', 'StrictHostKeyChecking=no',
|
146
|
+
'-l', username, dns_name, *args)
|
147
|
+
end
|
148
|
+
|
149
|
+
def scp_file(filename)
|
150
|
+
filename = File.expand_path(filename)
|
151
|
+
run_command('scp', '-o', 'StrictHostKeyChecking=no',
|
152
|
+
filename, "#{username}@#{dns_name}:", *ARGV[3..-1])
|
153
|
+
end
|
154
|
+
|
155
|
+
def bootstrap_livery
|
156
|
+
tarball = nil
|
157
|
+
if livery == :cwd
|
158
|
+
tarball = Blimpy::Livery.tarball_directory(Dir.pwd)
|
159
|
+
scp_file(tarball)
|
160
|
+
# HAXX
|
161
|
+
basename = File.basename(tarball)
|
162
|
+
puts 'Bootstrapping the livery'
|
163
|
+
ssh_into("tar -zxf #{basename} && cd #{File.basename(tarball, '.tar.gz')} && sudo ./bootstrap.sh")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def wait_for_sshd
|
168
|
+
return if @ssh_connected
|
124
169
|
start = Time.now.to_i
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
170
|
+
use_exec = @exec_commands
|
171
|
+
# Even if we are supposed to use #exec here, we wait to disable it until
|
172
|
+
# after sshd(8) comes online
|
173
|
+
@exec_commands = false
|
174
|
+
|
175
|
+
print "..waiting for sshd on #{@name} to come online"
|
176
|
+
until @ssh_connected
|
177
|
+
# Run the `true` command and exit
|
178
|
+
@ssh_connected = ssh_into('-q', 'true')
|
179
|
+
|
180
|
+
unless @ssh_connected
|
181
|
+
if (Time.now.to_i - start) < 30
|
182
|
+
print '.'
|
183
|
+
sleep 1
|
184
|
+
end
|
132
185
|
end
|
133
186
|
end
|
134
187
|
puts
|
135
|
-
|
188
|
+
@exec_commands = use_exec
|
136
189
|
end
|
137
190
|
|
138
191
|
private
|
data/lib/blimpy/cli.rb
CHANGED
@@ -15,6 +15,17 @@ module Blimpy
|
|
15
15
|
exit 1
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
def box_by_name(name)
|
20
|
+
fleet = Blimpy::Fleet.new
|
21
|
+
box = nil
|
22
|
+
fleet.members.each do |instance_id, data|
|
23
|
+
box_name = data['name']
|
24
|
+
next unless box_name == name
|
25
|
+
box = Blimpy::Box.from_instance_id(instance_id, data)
|
26
|
+
end
|
27
|
+
box
|
28
|
+
end
|
18
29
|
end
|
19
30
|
|
20
31
|
desc 'start', 'Start up a fleet of blimps'
|
@@ -84,19 +95,25 @@ end
|
|
84
95
|
desc 'ssh BLIMP_NAME', 'Log into a running blimp'
|
85
96
|
def ssh(name, *args)
|
86
97
|
ensure_blimpfile
|
87
|
-
|
88
|
-
box = nil
|
89
|
-
fleet.members.each do |instance_id, data|
|
90
|
-
box_name = data['name']
|
91
|
-
next unless box_name == name
|
92
|
-
box = Blimpy::Box.from_instance_id(instance_id, data)
|
93
|
-
end
|
98
|
+
box = box_by_name(name)
|
94
99
|
if box.nil?
|
95
|
-
puts "Could not find blimp named \"#{name}\""
|
100
|
+
puts "Could not find a blimp named \"#{name}\""
|
96
101
|
exit 1
|
97
102
|
end
|
98
|
-
|
103
|
+
box.wait_for_sshd
|
99
104
|
box.ssh_into
|
100
105
|
end
|
106
|
+
|
107
|
+
desc 'scp BLIMP_NAME FILE_NAME', 'Securely copy FILE_NAME into the blimp'
|
108
|
+
def scp(name, filename, *args)
|
109
|
+
ensure_blimpfile
|
110
|
+
box = box_by_name(name)
|
111
|
+
if box.nil?
|
112
|
+
puts "Could not find a blimp named \"#{name}\""
|
113
|
+
exit 1
|
114
|
+
end
|
115
|
+
box.wait_for_sshd
|
116
|
+
box.scp_file(filename)
|
117
|
+
end
|
101
118
|
end
|
102
119
|
end
|
data/lib/blimpy/fleet.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'zlib'
|
3
|
+
require 'archive/tar/minitar'
|
4
|
+
|
5
|
+
module Blimpy
|
6
|
+
class Livery
|
7
|
+
def self.tarball_directory(directory)
|
8
|
+
if directory.nil? || !(File.directory? directory)
|
9
|
+
raise ArgumentError, "The argument '#{directory}' doesn't appear to be a directory"
|
10
|
+
end
|
11
|
+
|
12
|
+
directory = File.expand_path(directory)
|
13
|
+
short_name = File.basename(directory)
|
14
|
+
|
15
|
+
tarball = nil
|
16
|
+
Dir.chdir(File.expand_path(directory + '/../')) do
|
17
|
+
tarball = self.gzip_for_directory(short_name, '/tmp') do |tgz|
|
18
|
+
Archive::Tar::Minitar.pack(short_name, tgz)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
tarball
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def self.gzip_for_directory(directory, root)
|
27
|
+
filename = File.join(root, "#{directory}.tar.gz")
|
28
|
+
yield Zlib::GzipWriter.new(File.open(filename, 'wb'))
|
29
|
+
filename
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/blimpy/version.rb
CHANGED
data/spec/blimpy/box_spec.rb
CHANGED
@@ -147,5 +147,21 @@ describe Blimpy::Box do
|
|
147
147
|
end
|
148
148
|
|
149
149
|
end
|
150
|
+
|
151
|
+
describe '#bootstrap_livery' do
|
152
|
+
context 'with a livery of :cwd' do
|
153
|
+
before :each do
|
154
|
+
subject.livery = :cwd
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should tarball up the current directory' do
|
158
|
+
Dir.should_receive(:pwd).and_return('mock-pwd')
|
159
|
+
Blimpy::Livery.should_receive(:tarball_directory).with('mock-pwd').and_return('mock-pwd.tar.gz')
|
160
|
+
subject.should_receive(:scp_file).with('mock-pwd.tar.gz')
|
161
|
+
subject.should_receive(:ssh_into)
|
162
|
+
subject.bootstrap_livery
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
150
166
|
end
|
151
167
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'blimpy/livery'
|
3
|
+
|
4
|
+
describe Blimpy::Livery do
|
5
|
+
context 'class methods' do
|
6
|
+
describe '#tarball_directory' do
|
7
|
+
subject { Blimpy::Livery } # No instantiating!
|
8
|
+
it 'should raise an exception if the directory doesn\'t exist' do
|
9
|
+
expect {
|
10
|
+
subject.tarball_directory(nil)
|
11
|
+
}.to raise_error(ArgumentError)
|
12
|
+
|
13
|
+
expect {
|
14
|
+
subject.tarball_directory('/tmp/never-gonna-give-you-up.lolz')
|
15
|
+
}.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blimpy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-29 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
16
|
-
requirement: &
|
16
|
+
requirement: &6248380 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *6248380
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: thor
|
27
|
-
requirement: &
|
27
|
+
requirement: &6247840 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,18 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *6247840
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: minitar
|
38
|
+
requirement: &6247360 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *6247360
|
36
47
|
description: Blimpy is a tool for managing a fleet of machines in the CLOUD!
|
37
48
|
email:
|
38
49
|
- tyler@monkeypox.org
|
@@ -50,6 +61,7 @@ files:
|
|
50
61
|
- blimpy.gemspec
|
51
62
|
- features/cli/init.feature
|
52
63
|
- features/cli/list.feature
|
64
|
+
- features/cli/scp.feature
|
53
65
|
- features/cli/ssh.feature
|
54
66
|
- features/cli/start.feature
|
55
67
|
- features/step_definitions/cli_steps.rb
|
@@ -62,12 +74,14 @@ files:
|
|
62
74
|
- lib/blimpy/fleet.rb
|
63
75
|
- lib/blimpy/helpers/state.rb
|
64
76
|
- lib/blimpy/keys.rb
|
77
|
+
- lib/blimpy/livery.rb
|
65
78
|
- lib/blimpy/version.rb
|
66
79
|
- spec/blimpy/box_spec.rb
|
67
80
|
- spec/blimpy/engine_spec.rb
|
68
81
|
- spec/blimpy/fleet_spec.rb
|
69
82
|
- spec/blimpy/helpers/state_spec.rb
|
70
83
|
- spec/blimpy/keys_spec.rb
|
84
|
+
- spec/blimpy/livery_spec.rb
|
71
85
|
- spec/blimpy_spec.rb
|
72
86
|
- spec/spec_helper.rb
|
73
87
|
homepage: https://github.com/rtyler/blimpy
|
@@ -97,6 +111,7 @@ summary: Ruby + CLOUD = Blimpy
|
|
97
111
|
test_files:
|
98
112
|
- features/cli/init.feature
|
99
113
|
- features/cli/list.feature
|
114
|
+
- features/cli/scp.feature
|
100
115
|
- features/cli/ssh.feature
|
101
116
|
- features/cli/start.feature
|
102
117
|
- features/step_definitions/cli_steps.rb
|
@@ -107,5 +122,6 @@ test_files:
|
|
107
122
|
- spec/blimpy/fleet_spec.rb
|
108
123
|
- spec/blimpy/helpers/state_spec.rb
|
109
124
|
- spec/blimpy/keys_spec.rb
|
125
|
+
- spec/blimpy/livery_spec.rb
|
110
126
|
- spec/blimpy_spec.rb
|
111
127
|
- spec/spec_helper.rb
|