management 0.9 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -26,9 +26,9 @@ build/
26
26
 
27
27
  # for a library or gem, you might want to ignore these files since the code is
28
28
  # intended to run in multiple environments; otherwise, check them in:
29
- # Gemfile.lock
30
- # .ruby-version
31
- # .ruby-gemset
29
+ Gemfile.lock
30
+ .ruby-version
31
+ .ruby-gemset
32
32
 
33
33
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
34
  .rvmrc
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Minimalist EC2 configuration & deployment tool.
4
4
 
5
- - Version: **0.9**
5
+ - Version: **1.0**
6
6
 
7
7
  ![build status](https://travis-ci.org/sdegutis/management.svg?branch=master)
8
8
 
data/bin/management CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require_relative '../lib/management.rb'
4
- Management::Interpreter.interpret! ARGV.dup
4
+ Management.interpret! ARGV
data/lib/ext/fog.rb CHANGED
@@ -65,10 +65,10 @@ class Fog::Compute::Server
65
65
  end
66
66
 
67
67
  def extract_tar(remote_tar_path)
68
- ssh("tar -xzf #{remote_tar_path} -C /")
68
+ ssh("sudo tar -xzf #{remote_tar_path} -C /")
69
69
  end
70
70
 
71
71
  def chown_r(remote_path, chown)
72
- ssh("chown -R #{chown} #{remote_path}")
72
+ ssh("sudo chown -R #{chown} #{remote_path}")
73
73
  end
74
74
  end
@@ -1,95 +1,42 @@
1
- require 'fog'
2
- require 'yaml'
3
-
4
1
  module Management
5
2
 
6
3
  class Command
7
4
 
8
- class << self
9
-
10
- def all
11
- @all ||= []
12
- end
13
-
14
- def inherited(subclass)
15
- all << subclass
16
- end
17
-
18
- def help_string
19
- params = instance_method(:call).parameters
20
-
21
- output = sprintf("%20s ", command_name)
22
- args = []
23
-
24
- params.each do |req, name|
25
- name = "<#{name.to_s.sub('_name', '')}>"
26
- if req == :opt
27
- name = "[#{name}]"
28
- end
29
- args << name
30
- end
31
-
32
- return output + args.join(' ')
33
- end
34
-
35
- def command_name
36
- self.name.split('::').last.
37
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
38
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
39
- tr("_", "-").
40
- downcase
41
- end
42
-
5
+ def self.all
6
+ @all ||= []
43
7
  end
44
8
 
45
-
46
- def get_env(name)
47
- return nil if name.nil?
48
- config[:envs].include?(name) and name or invalid_selection "Invalid environment: #{name}", config[:envs]
49
- end
50
-
51
- def get_type(name)
52
- config[:types][name.to_sym] or invalid_selection "Invalid type: #{name}", config[:types].map(&:first)
53
- end
54
-
55
- def get_script(name)
56
- config[:scripts][name.to_sym] or invalid_selection "Invalid script: #{name}", config[:scripts].map(&:first)
9
+ def self.inherited(subclass)
10
+ all << subclass.new
57
11
  end
58
12
 
59
- def get_server(name)
60
- servers = cloud.servers
61
- servers.find{|server| server.name == name} or invalid_selection "Invalid server: #{name}", servers.map(&:name)
13
+ def fn
14
+ method(:run)
62
15
  end
63
16
 
64
- def config
65
- @config ||= symbolize_keys!(raw_yaml)
17
+ def command_name
18
+ self.class.name.split('::').last.
19
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
20
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
21
+ tr("_", "-").
22
+ downcase
66
23
  end
67
24
 
68
- def cloud
69
- @cloud ||= Fog::Compute.new(config[:cloud])
25
+ def help_string
26
+ return sprintf("%20s ", self.command_name) + fn.parameters.map do |req, name|
27
+ name = "<#{name.to_s.sub('_name', '')}>"
28
+ req == :opt ? "[#{name}]" : name
29
+ end.join(' ')
70
30
  end
71
31
 
32
+ def call_with(args, error_handler)
33
+ num_all_args = fn.parameters.count
34
+ num_req_args = fn.arity
72
35
 
73
- private
74
-
75
- def raw_yaml
76
- YAML.load(File.read("management_config.yml"))
77
- end
78
-
79
- def invalid_selection(str, selection)
80
- abort "#{str}\nValid choices:" + (["\n"] + selection).join("\n - ")
81
- end
36
+ error_handler.call "not enough arguments" if args.count < num_req_args
37
+ error_handler.call "too many arguments" if args.count > num_all_args
82
38
 
83
- def symbolize_keys! h
84
- case h
85
- when Hash
86
- pairs = h.map { |k, v| [k.respond_to?(:to_sym) ? k.to_sym : k, symbolize_keys!(v)] }
87
- return Hash[pairs]
88
- when Array
89
- return h.map{ |e| symbolize_keys!(e) }
90
- else
91
- return h
92
- end
39
+ fn.call *args
93
40
  end
94
41
 
95
42
  end
@@ -4,11 +4,13 @@ module Management
4
4
 
5
5
  class CreateServer < Management::Command
6
6
 
7
- def call(env_name, type_name)
7
+ include Management::Helper
8
+
9
+ def run(env_name, type_name)
8
10
  env = get_env(env_name)
9
11
  type = get_type(type_name)
10
12
 
11
- servers = cloud.servers
13
+ servers = live_servers
12
14
  name = make_unique_server_name(env_name, type_name, servers)
13
15
 
14
16
  puts "Creating \"#{name}\"..."
@@ -4,7 +4,9 @@ module Management
4
4
 
5
5
  class DestroyServer < Management::Command
6
6
 
7
- def call(server_name)
7
+ include Management::Helper
8
+
9
+ def run(server_name)
8
10
  server = get_server(server_name)
9
11
 
10
12
  print "Are you sure you want to do this? Type 'Yes' to continue, or anything else to abort: "
@@ -4,7 +4,9 @@ module Management
4
4
 
5
5
  class ListServers < Management::Command
6
6
 
7
- def call(env_name = nil)
7
+ include Management::Helper
8
+
9
+ def run(env_name = nil)
8
10
  env = get_env(env_name)
9
11
 
10
12
  cols = [
@@ -23,7 +25,7 @@ module Management
23
25
  send :printf, *([format].concat(cols.map{|c|c[:title]}))
24
26
  send :printf, *([format].concat(cols.map{|c|'-' * c[:size]}))
25
27
 
26
- servers = cloud.servers.sort_by(&:name)
28
+ servers = live_servers.sort_by(&:name)
27
29
 
28
30
  servers.each do |server|
29
31
  next if env_name && server.env != env_name
@@ -8,7 +8,9 @@ module Management
8
8
 
9
9
  class RunScript < Management::Command
10
10
 
11
- def call(server_name, script_name)
11
+ include Management::Helper
12
+
13
+ def run(server_name, script_name)
12
14
  server = get_server(server_name)
13
15
  script = get_script(script_name)
14
16
 
@@ -24,7 +26,7 @@ module Management
24
26
  when :copy
25
27
  copy_file(server, *data)
26
28
  when :run
27
- run_command(server, data)
29
+ run_remote_command(server, data)
28
30
  end
29
31
 
30
32
  end
@@ -68,7 +70,7 @@ module Management
68
70
 
69
71
  end
70
72
 
71
- def run_command(server, cmd)
73
+ def run_remote_command(server, cmd)
72
74
  puts "Running #{cmd}"
73
75
 
74
76
  result = server.ssh("#{cmd}").first
@@ -4,18 +4,15 @@ module Management
4
4
 
5
5
  class SshServer < Management::Command
6
6
 
7
- def call(server_name)
7
+ include Management::Helper
8
+
9
+ def run(server_name)
8
10
  server = get_server(server_name)
9
11
 
10
12
  type = config[:types][server.type.to_sym]
11
13
  ssh_key_path = type[:ssh_key_path]
12
- run "chmod 0600 #{ssh_key_path}"
13
- run "ssh -i #{ssh_key_path} #{config[:root_user]}@#{server.public_ip_address}"
14
- end
15
-
16
- def run(cmd)
17
- puts "Running: #{cmd}"
18
- system cmd
14
+ system_verbose "chmod 0600 #{ssh_key_path}"
15
+ system_verbose "ssh -i #{ssh_key_path} #{config[:root_user]}@#{server.public_ip_address}"
19
16
  end
20
17
 
21
18
  end
@@ -0,0 +1,17 @@
1
+ require_relative '../command'
2
+
3
+ module Management
4
+
5
+ class StartServer < Management::Command
6
+
7
+ include Management::Helper
8
+
9
+ def run(server_name)
10
+ server = get_server(server_name)
11
+ server.start
12
+ puts "Started #{server_name}."
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -4,7 +4,9 @@ module Management
4
4
 
5
5
  class StopServer < Management::Command
6
6
 
7
- def call(server_name)
7
+ include Management::Helper
8
+
9
+ def run(server_name)
8
10
  server = get_server(server_name)
9
11
  server.stop
10
12
  puts "Stopped #{server_name}."
@@ -0,0 +1,70 @@
1
+ require 'fog'
2
+ require 'yaml'
3
+
4
+ module Management
5
+
6
+ module Helper
7
+
8
+ def get_env(name)
9
+ return nil if name.nil?
10
+ config[:envs].include?(name) and name or invalid_selection "Invalid environment: #{name}", config[:envs]
11
+ end
12
+
13
+ def get_type(name)
14
+ config[:types][name.to_sym] or invalid_selection "Invalid type: #{name}", config[:types].map(&:first)
15
+ end
16
+
17
+ def get_script(name)
18
+ config[:scripts][name.to_sym] or invalid_selection "Invalid script: #{name}", config[:scripts].map(&:first)
19
+ end
20
+
21
+ def get_server(name)
22
+ servers = live_servers
23
+ server = servers.find{|server| server.name == name} or invalid_selection "Invalid server: #{name}", servers.map(&:name)
24
+ server.username = config[:root_user] if server && config[:root_user]
25
+ server
26
+ end
27
+
28
+ def live_servers
29
+ cloud.servers.reject{ |s| s.state == 'terminated' }
30
+ end
31
+
32
+ def config
33
+ @config ||= symbolize_keys!(raw_yaml)
34
+ end
35
+
36
+ def cloud
37
+ @cloud ||= Fog::Compute.new(config[:cloud])
38
+ end
39
+
40
+ def system_verbose(cmd)
41
+ puts "Running: #{cmd}"
42
+ system cmd
43
+ end
44
+
45
+
46
+ private
47
+
48
+ def raw_yaml
49
+ YAML.load(File.read("management_config.yml"))
50
+ end
51
+
52
+ def invalid_selection(str, selection)
53
+ abort "#{str}\nValid choices:" + (["\n"] + selection).join("\n - ")
54
+ end
55
+
56
+ def symbolize_keys! h
57
+ case h
58
+ when Hash
59
+ pairs = h.map { |k, v| [k.respond_to?(:to_sym) ? k.to_sym : k, symbolize_keys!(v)] }
60
+ return Hash[pairs]
61
+ when Array
62
+ return h.map{ |e| symbolize_keys!(e) }
63
+ else
64
+ return h
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -2,50 +2,29 @@ require 'optparse'
2
2
 
3
3
  module Management
4
4
 
5
- class Interpreter
6
-
7
- class << self
8
-
9
- def interpret!(input)
10
- commands = Management::Command.all
11
-
12
- parser = OptionParser.new do |opts|
13
- opts.banner = "Usage:"
14
- opts.separator('')
15
- commands.each { |cmd| opts.separator cmd.help_string }
16
- opts.separator('')
17
- opts.on('-h', '--help', 'Display this screen') { puts opts; exit }
18
- opts.on('-v', '--version', 'Show version') { puts Management::VERSION; exit }
19
- end
20
-
21
- abort parser.help if input.empty?
22
-
23
- args = parser.parse(input)
24
- task = args.shift
25
- ARGV.clear
26
-
27
- if chosen_command = commands.find{|c|c.command_name == task}
28
- all_args = chosen_command.instance_method(:call).parameters
29
- req_args = all_args.map(&:first).take_while{|p| p == :req}
30
-
31
- case
32
- when args.count < req_args.count
33
- puts "Error: not enough arguments"
34
- abort parser.help
35
- when args.count > all_args.count
36
- puts "Error: too many arguments"
37
- abort parser.help
38
- else
39
- chosen_command.new.call(*args)
40
- end
41
- else
42
- puts "Error: unknown task \"#{task}\""
43
- abort parser.help
44
- end
45
- end
46
-
5
+ def self.interpret!(argv)
6
+ commands = Management::Command.all
7
+
8
+ parser = OptionParser.new do |opts|
9
+ opts.banner = "Usage: management [command] [args*]"
10
+ opts.separator('')
11
+ opts.separator('Commands:')
12
+ commands.each { |command| opts.separator command.help_string }
13
+ opts.separator('')
14
+ opts.on('-h', '--help', 'Display this screen') { puts opts; exit }
15
+ opts.on('-v', '--version', 'Show version') { puts Management::VERSION; exit }
47
16
  end
48
17
 
18
+ abort parser.help if argv.empty?
19
+ error_handler = lambda { |e| abort "Error: #{e}\n\n" + parser.help }
20
+
21
+ args = parser.parse(argv)
22
+ task = args.shift
23
+
24
+ command = commands.find{|c|c.command_name == task}
25
+ error_handler.call "unknown task \"#{task}\"" if command.nil?
26
+
27
+ command.call_with(args, error_handler)
49
28
  end
50
29
 
51
30
  end
@@ -1,3 +1,3 @@
1
1
  module Management
2
- VERSION = "0.9"
2
+ VERSION = "1.0"
3
3
  end
data/lib/management.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  require_relative 'ext/fog'
2
-
3
2
  require_relative 'management/version'
4
3
  require_relative 'management/interpreter'
4
+ require_relative 'management/helper'
5
+ require_relative 'management/command'
5
6
  require_relative 'management/commands/create_server'
6
7
  require_relative 'management/commands/list_servers'
7
8
  require_relative 'management/commands/destroy_server'
9
+ require_relative 'management/commands/start_server'
10
+ require_relative 'management/commands/stop_server'
8
11
  require_relative 'management/commands/run_script'
9
12
  require_relative 'management/commands/ssh_server'
10
- require_relative 'management/commands/stop_server'
data/management.gemspec CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Steven Degutis"]
10
10
  s.homepage = 'https://github.com/sdegutis/management'
11
11
  s.license = 'MIT'
12
- s.summary = "Minimalist EC2 management & deployment tool."
13
- s.description = "Write your deployment using just shell scripts."
12
+ s.summary =
13
+ s.description = "Minimalist EC2 configuration & deployment tool."
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.test_files = `git ls-files -- spec/*`.split("\n")
16
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -22,6 +22,6 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency 'rake'
23
23
  s.add_development_dependency 'pry'
24
24
  s.add_development_dependency 'fakefs'
25
- s.add_development_dependency 'rspec'
25
+ s.add_development_dependency 'rspec', '~> 3.0.0'
26
26
  s.add_development_dependency 'guard-rspec'
27
27
  end
data/spec/main_spec.rb CHANGED
@@ -38,9 +38,11 @@ def without_stderr old = $stderr; $stderr = StringIO.new; yield; $stderr = old e
38
38
 
39
39
  describe 'management' do
40
40
 
41
- before { subject.stub(:raw_yaml).and_return(YAML.load(SampleConfig)) }
41
+ before { subject.define_singleton_method(:raw_yaml) { YAML.load(SampleConfig) } }
42
42
 
43
- describe Management::Command do
43
+ describe Management::Helper do
44
+
45
+ subject { Object.new.extend Management::Helper }
44
46
 
45
47
  describe "safely getting config values" do
46
48
 
@@ -74,35 +76,35 @@ describe 'management' do
74
76
  FileUtils.mkdir_p("/foo/bar/baz")
75
77
  File.write("/foo/bar/baz/quux", "woot")
76
78
  File.write("/foo/bar/baz/zap", "wat")
77
- subject.relevant_files("/").should == ["./foo/bar/baz/quux", "./foo/bar/baz/zap"]
79
+ expect( subject.relevant_files("/") ).to eq ["./foo/bar/baz/quux", "./foo/bar/baz/zap"]
78
80
  end
79
81
 
80
82
  it "finds empty leaf directories in the tree" do
81
83
  FileUtils.mkdir_p("/foo/bar/baz")
82
84
  File.write("/foo/bar/baz/quux", "woot")
83
85
  FileUtils.mkdir_p("/foo/bar/baz/zap")
84
- subject.relevant_files("/").should == ["./foo/bar/baz/quux", "./foo/bar/baz/zap"]
86
+ expect( subject.relevant_files("/") ).to eq ["./foo/bar/baz/quux", "./foo/bar/baz/zap"]
85
87
  end
86
88
 
87
89
  it "returns dot files" do
88
90
  FileUtils.mkdir_p("/foo/bar/baz")
89
91
  File.write("/foo/bar/baz/.quux", "woot")
90
92
  FileUtils.mkdir_p("/foo/bar/baz/.zap")
91
- subject.relevant_files("/").should == ["./foo/bar/baz/.quux", "./foo/bar/baz/.zap"]
93
+ expect( subject.relevant_files("/") ).to eq ["./foo/bar/baz/.quux", "./foo/bar/baz/.zap"]
92
94
  end
93
95
 
94
96
  it "returns relative filenames" do
95
97
  FileUtils.mkdir_p("/foo/bar/baz")
96
98
  File.write("/foo/bar/baz/quux", "woot")
97
99
  FileUtils.mkdir_p("/foo/bar/baz/zap")
98
- subject.relevant_files("/foo/bar").should == ["./baz/quux", "./baz/zap"]
100
+ expect( subject.relevant_files("/foo/bar") ).to eq ["./baz/quux", "./baz/zap"]
99
101
  end
100
102
 
101
103
  it "returns relative filenames, even when you add a trailing slash" do
102
104
  FileUtils.mkdir_p("/foo/bar/baz")
103
105
  File.write("/foo/bar/baz/quux", "woot")
104
106
  FileUtils.mkdir_p("/foo/bar/baz/zap")
105
- subject.relevant_files("/foo/bar/").should == ["./baz/quux", "./baz/zap"]
107
+ expect( subject.relevant_files("/foo/bar/") ).to eq ["./baz/quux", "./baz/zap"]
106
108
  end
107
109
 
108
110
  it "requires an absolute path" do
@@ -114,7 +116,7 @@ describe 'management' do
114
116
 
115
117
  describe "copying files over" do
116
118
 
117
- let(:server) { Object.new }
119
+ let(:server) { double 'server' }
118
120
 
119
121
  before(:each) do
120
122
 
@@ -152,13 +154,13 @@ describe 'management' do
152
154
  it "copies file contents into their remote paths" do
153
155
  File.write("foo", "the contents of foo")
154
156
  without_stdout { subject.copy_file(server, "foo", "/remote/foo") }
155
- File.read("/fake-remote-dir/remote/foo").should == "the contents of foo"
157
+ expect( File.read("/fake-remote-dir/remote/foo") ).to eq "the contents of foo"
156
158
  end
157
159
 
158
160
  it "templates files correctly" do
159
161
  File.write("foo", "the contents of <%= server.env %>")
160
162
  without_stdout { subject.copy_file(server, "foo", "/remote/foo", template: true) }
161
- File.read("/fake-remote-dir/remote/foo").should == "the contents of staging"
163
+ expect( File.read("/fake-remote-dir/remote/foo") ).to eq "the contents of staging"
162
164
  end
163
165
 
164
166
  it "chowns files correctly when specified" do
@@ -169,8 +171,8 @@ describe 'management' do
169
171
  without_stdout { subject.copy_file(server, "foo", "/remote/foo", chown: "#{user}:#{group}") }
170
172
 
171
173
  stats = File.stat("/fake-remote-dir/remote/foo")
172
- Etc.getpwuid(stats.uid).name.should == user
173
- Etc.getgrgid(stats.gid).name.should == group
174
+ expect( Etc.getpwuid(stats.uid).name ).to eq user
175
+ expect( Etc.getgrgid(stats.gid).name ).to eq group
174
176
  end
175
177
 
176
178
  it "doesn't chown anything unless specified" do
@@ -178,14 +180,14 @@ describe 'management' do
178
180
  without_stdout { subject.copy_file(server, "foo", "/remote/foo") }
179
181
 
180
182
  stats = File.stat("/fake-remote-dir/remote/foo")
181
- Etc.getpwuid(stats.uid).name.should == `id -un`.chomp
182
- Etc.getgrgid(stats.gid).name.should == `id -gn`.chomp
183
+ expect( Etc.getpwuid(stats.uid).name ).to eq `id -un`.chomp
184
+ expect( Etc.getgrgid(stats.gid).name ).to eq `id -gn`.chomp
183
185
  end
184
186
 
185
187
  it "fails if multiple local paths don't exist" do
186
188
  script = subject.get_script("testing")
187
189
  list = subject.missing_local_files(script)
188
- list.should == ["resources/testing.sh", "resources/web.conf.erb"]
190
+ expect(list).to eq ["resources/testing.sh", "resources/web.conf.erb"]
189
191
  end
190
192
 
191
193
  it "fails if a single local path doesn't exist" do
@@ -193,7 +195,7 @@ describe 'management' do
193
195
  File.write "resources/testing.sh", "hello world"
194
196
  script = subject.get_script("testing")
195
197
  list = subject.missing_local_files(script)
196
- list.should == ["resources/web.conf.erb"]
198
+ expect(list).to eq ["resources/web.conf.erb"]
197
199
  end
198
200
 
199
201
  end
@@ -208,33 +210,33 @@ describe 'management' do
208
210
  fake_server.new('production-web-1'),
209
211
  fake_server.new('staging-web-2')]
210
212
 
211
- subject.make_unique_server_name("staging", "web", []).should == "staging-web-1"
212
- subject.make_unique_server_name("staging", "web", servers).should == "staging-web-3"
213
- subject.make_unique_server_name("production", "web", servers).should == "production-web-2"
213
+ expect( subject.make_unique_server_name("staging", "web", []) ).to eq "staging-web-1"
214
+ expect( subject.make_unique_server_name("staging", "web", servers) ).to eq "staging-web-3"
215
+ expect( subject.make_unique_server_name("production", "web", servers) ).to eq "production-web-2"
214
216
  end
215
217
 
216
218
  end
217
219
 
218
220
  describe Management::DestroyServer do
219
221
 
220
- let(:server) { Object.new }
221
- before { subject.stub(:get_server).with("server-1").and_return(server) }
222
+ let(:server) { double "server" }
223
+ before { allow(subject).to receive(:get_server).with("server-1").and_return(server) }
222
224
 
223
225
  it "destroys the given server if you type 'Yes' verbatim" do
224
- server.should_receive(:destroy).once
225
- with_stdin("Yes\n") { without_stdout { subject.call("server-1") } }
226
+ expect(server).to receive(:destroy).once
227
+ with_stdin("Yes\n") { without_stdout { subject.run("server-1") } }
226
228
  end
227
229
 
228
230
  it "does not destroy the given server if you don't type 'Yes' verbatim" do
229
- server.should_not_receive(:destroy)
231
+ expect(server).not_to receive(:destroy)
230
232
  without_stdout do
231
- with_stdin("yes\n") { subject.call("server-1") }
232
- with_stdin("Y\n") { subject.call("server-1") }
233
- with_stdin("y\n") { subject.call("server-1") }
234
- with_stdin("yep\n") { subject.call("server-1") }
235
- with_stdin("\n") { subject.call("server-1") }
236
- with_stdin("YES\n") { subject.call("server-1") }
237
- with_stdin("Yes.\n") { subject.call("server-1") }
233
+ with_stdin("yes\n") { subject.run("server-1") }
234
+ with_stdin("Y\n") { subject.run("server-1") }
235
+ with_stdin("y\n") { subject.run("server-1") }
236
+ with_stdin("yep\n") { subject.run("server-1") }
237
+ with_stdin("\n") { subject.run("server-1") }
238
+ with_stdin("YES\n") { subject.run("server-1") }
239
+ with_stdin("Yes.\n") { subject.run("server-1") }
238
240
  end
239
241
  end
240
242
 
@@ -242,13 +244,13 @@ describe 'management' do
242
244
 
243
245
  describe Management::StopServer do
244
246
 
245
- let(:server) { Object.new }
246
- before { subject.stub(:get_server).with("server-1").and_return(server) }
247
+ let(:server) { double "server" }
248
+ before { allow(subject).to receive(:get_server).with("server-1").and_return(server) }
247
249
 
248
250
  it "stops the given server" do
249
- server.should_not_receive(:destroy)
250
- server.should_receive(:stop).once
251
- without_stdout { subject.call("server-1") }
251
+ expect(server).not_to receive(:destroy)
252
+ expect(server).to receive(:stop).once
253
+ without_stdout { subject.run("server-1") }
252
254
  end
253
255
 
254
256
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: management
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.9'
4
+ version: '1.0'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -96,17 +96,17 @@ dependencies:
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ! '>='
99
+ - - ~>
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: 3.0.0
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
- - - ! '>='
107
+ - - ~>
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: 3.0.0
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: guard-rspec
112
112
  requirement: !ruby/object:Gem::Requirement
@@ -123,7 +123,7 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
- description: Write your deployment using just shell scripts.
126
+ description: Minimalist EC2 configuration & deployment tool.
127
127
  email: steven@cleancoders.com
128
128
  executables:
129
129
  - management
@@ -133,7 +133,6 @@ files:
133
133
  - .gitignore
134
134
  - .travis.yml
135
135
  - Gemfile
136
- - Gemfile.lock
137
136
  - Guardfile
138
137
  - README.md
139
138
  - Rakefile
@@ -146,7 +145,9 @@ files:
146
145
  - lib/management/commands/list_servers.rb
147
146
  - lib/management/commands/run_script.rb
148
147
  - lib/management/commands/ssh_server.rb
148
+ - lib/management/commands/start_server.rb
149
149
  - lib/management/commands/stop_server.rb
150
+ - lib/management/helper.rb
150
151
  - lib/management/interpreter.rb
151
152
  - lib/management/version.rb
152
153
  - management.gemspec
@@ -175,6 +176,6 @@ rubyforge_project:
175
176
  rubygems_version: 1.8.23.2
176
177
  signing_key:
177
178
  specification_version: 3
178
- summary: Minimalist EC2 management & deployment tool.
179
+ summary: Minimalist EC2 configuration & deployment tool.
179
180
  test_files:
180
181
  - spec/main_spec.rb
data/Gemfile.lock DELETED
@@ -1,86 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- specs:
4
- builder (3.2.2)
5
- celluloid (0.15.2)
6
- timers (~> 1.1.0)
7
- coderay (1.1.0)
8
- diff-lcs (1.2.5)
9
- excon (0.32.1)
10
- fakefs (0.5.2)
11
- ffi (1.9.3)
12
- fog (1.21.0)
13
- fog-brightbox
14
- fog-core (~> 1.21, >= 1.21.1)
15
- fog-json
16
- nokogiri (~> 1.5, >= 1.5.11)
17
- fog-brightbox (0.0.1)
18
- fog-core
19
- fog-json
20
- fog-core (1.21.1)
21
- builder
22
- excon (~> 0.32)
23
- formatador (~> 0.2.0)
24
- mime-types
25
- net-scp (~> 1.1)
26
- net-ssh (>= 2.1.3)
27
- fog-json (1.0.0)
28
- multi_json (~> 1.0)
29
- formatador (0.2.4)
30
- guard (2.6.1)
31
- formatador (>= 0.2.4)
32
- listen (~> 2.7)
33
- lumberjack (~> 1.0)
34
- pry (>= 0.9.12)
35
- thor (>= 0.18.1)
36
- guard-rspec (4.2.9)
37
- guard (~> 2.1)
38
- rspec (>= 2.14, < 4.0)
39
- listen (2.7.7)
40
- celluloid (>= 0.15.2)
41
- rb-fsevent (>= 0.9.3)
42
- rb-inotify (>= 0.9)
43
- lumberjack (1.0.6)
44
- method_source (0.8.2)
45
- mime-types (2.2)
46
- mini_portile (0.5.3)
47
- multi_json (1.9.2)
48
- net-scp (1.1.2)
49
- net-ssh (>= 2.6.5)
50
- net-ssh (2.8.0)
51
- nokogiri (1.6.1)
52
- mini_portile (~> 0.5.0)
53
- pry (0.9.12.6)
54
- coderay (~> 1.0)
55
- method_source (~> 0.8)
56
- slop (~> 3.4)
57
- rake (10.3.2)
58
- rb-fsevent (0.9.4)
59
- rb-inotify (0.9.5)
60
- ffi (>= 0.5.0)
61
- rspec (2.14.1)
62
- rspec-core (~> 2.14.0)
63
- rspec-expectations (~> 2.14.0)
64
- rspec-mocks (~> 2.14.0)
65
- rspec-core (2.14.8)
66
- rspec-expectations (2.14.5)
67
- diff-lcs (>= 1.1.3, < 2.0)
68
- rspec-mocks (2.14.6)
69
- slop (3.5.0)
70
- thor (0.19.1)
71
- timers (1.1.0)
72
- unf (0.1.4)
73
- unf_ext
74
- unf_ext (0.0.6)
75
-
76
- PLATFORMS
77
- ruby
78
-
79
- DEPENDENCIES
80
- fakefs
81
- fog
82
- guard-rspec
83
- pry
84
- rake
85
- rspec
86
- unf