ftl 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,3 +1,15 @@
1
+ # Release Version 0.3.0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
+
3
+ * Feature: Add ftl <script> to execute arbitrary ruby locally within ftl environment
4
+ * Feature: Add ftl ips to show Elastic IP addresses
5
+ * Feature: Add ftl stop to stop running instances
6
+ * Feature: Add ftl start to start running instances
7
+ * Feature: Add option to pass in spot request instance count
8
+ * Feature: Add ftl terminate to specifically terminate any instance vs only running ones
9
+ * Bug fix: Spot requests were launching as regular instances
10
+ * Bug fix: Other minor bug fixes and cleanups
11
+
12
+
1
13
  # Release Version 0.2.4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
14
 
3
15
  * Add ftl <action> <server> to execute arbitrary commands on running instances
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ftl (0.2.4)
4
+ ftl (0.3.0)
5
5
  fog
6
6
  formatador (~> 0.2.2)
7
+ tilt
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -22,11 +23,11 @@ GEM
22
23
  gherkin (~> 2.10.0)
23
24
  json (>= 1.4.6)
24
25
  diff-lcs (1.1.3)
25
- excon (0.13.4)
26
+ excon (0.14.3)
26
27
  ffi (1.0.11)
27
- fog (1.3.1)
28
+ fog (1.4.0)
28
29
  builder
29
- excon (~> 0.13.0)
30
+ excon (~> 0.14.0)
30
31
  formatador (~> 0.2.0)
31
32
  mime-types
32
33
  multi_json (~> 1.0)
@@ -34,18 +35,16 @@ GEM
34
35
  net-ssh (>= 2.1.3)
35
36
  nokogiri (~> 1.5.0)
36
37
  ruby-hmac
37
- formatador (0.2.2)
38
+ formatador (0.2.3)
38
39
  gherkin (2.10.0)
39
40
  json (>= 1.4.6)
40
- jruby-pageant (1.0.2)
41
41
  json (1.7.3)
42
- mime-types (1.18)
43
- multi_json (1.3.5)
42
+ mime-types (1.19)
43
+ multi_json (1.3.6)
44
44
  net-scp (1.0.4)
45
45
  net-ssh (>= 1.99.1)
46
- net-ssh (2.4.0)
47
- jruby-pageant (>= 1.0.2)
48
- nokogiri (1.5.2)
46
+ net-ssh (2.5.2)
47
+ nokogiri (1.5.5)
49
48
  rake (0.9.2.2)
50
49
  rdoc (3.12)
51
50
  json (~> 1.4)
@@ -58,6 +57,7 @@ GEM
58
57
  diff-lcs (~> 1.1.3)
59
58
  rspec-mocks (2.10.1)
60
59
  ruby-hmac (0.4.0)
60
+ tilt (1.3.3)
61
61
 
62
62
  PLATFORMS
63
63
  ruby
@@ -19,4 +19,5 @@ Gem::Specification.new do |gem|
19
19
  gem.add_development_dependency('rake','~> 0.9.2')
20
20
  gem.add_dependency('fog')
21
21
  gem.add_dependency('formatador', '~> 0.2.2')
22
+ gem.add_dependency('tilt')
22
23
  end
data/lib/ftl.rb CHANGED
@@ -7,6 +7,7 @@ require 'formatador'
7
7
  require 'ftl/fog_lights'
8
8
  require 'ftl/formatador_table'
9
9
 
10
+
10
11
  module Ftl
11
- # I'm a module!
12
+ # Look at me, I'm a module!
12
13
  end
@@ -22,6 +22,7 @@ module Ftl
22
22
  ftl edit # Edit ftl.yml with your $EDITOR
23
23
  ftl images # Show AMIs associated with your account
24
24
  ftl <action> ninja # Execute the <action> (specified in ftl.yml) on the remote server instance
25
+ ftl <script> ninja # Execute the <script> (specified in ftl.yml) on your local machine
25
26
  ftl --config=~/ftl.yml servers # Uses custom config file
26
27
  ftl --headers=id,tags.Name servers # Uses specified headers
27
28
  ftl --version # Show version number
@@ -40,17 +41,14 @@ module Ftl
40
41
  attr_accessor :options
41
42
 
42
43
  def initialize(args=nil, opts={})
43
- load_config(opts)
44
44
  if args && args.length > 0
45
45
  arg = args.reverse.pop
46
+ @args = [arg, args - [arg]]
47
+ load_config(opts)
46
48
  if (!SINGLE_COMMANDS.include?(arg))
47
49
  @con = Fog::Compute.new(:provider => 'AWS', :aws_secret_access_key => options['SECRET_ACCESS_KEY'], :aws_access_key_id => options['ACCESS_KEY_ID'])
48
50
  end
49
- begin
50
- send(arg, args - [arg])
51
- rescue
52
- Ftl.help
53
- end
51
+ send(*@args)
54
52
  else
55
53
  Ftl.help
56
54
  end
@@ -59,12 +57,14 @@ module Ftl
59
57
  def launch_instance(args)
60
58
  display "Spinning up FTL..."
61
59
  opts = options
62
- opts = options[:templates][args.first.to_sym] if !options[:templates][args.first.to_sym].nil?
60
+ opts = options.merge(options[:templates][args.first.to_sym]) if !options[:templates][args.first.to_sym].nil?
63
61
 
64
62
  opts[:group_ids] = (opts[:group_ids] || []) + opts[:groups].select { | group | group.to_s =~ /^sg-[0-9a-f]{8}$/ }
65
63
  opts[:groups] = opts[:groups].reject { | group | group.to_s =~ /^sg-[0-9a-f]{8}$/ }
66
64
 
67
- server = con.servers.create(:user_data => opts[:user_data],
65
+ launcher = options.delete(:launcher) || :servers
66
+ server = con.send(launcher).create(
67
+ :user_data => opts[:user_data],
68
68
  :key_name => opts[:keypair],
69
69
  :groups => opts[:groups],
70
70
  :security_group_ids => opts[:group_ids],
@@ -75,6 +75,8 @@ module Ftl
75
75
  :tags => opts[:tags].merge(:Name => args.first),
76
76
  :subnet_id => opts[:subnet_id],
77
77
  :private_ip_address => opts[:ip_private],
78
+ :ip_address => opts[:ip_address],
79
+ :price => opts[:price]
78
80
  )
79
81
 
80
82
  display server
@@ -84,7 +86,6 @@ module Ftl
84
86
 
85
87
  def launch(args={})
86
88
  guard(args.first, "Please provide a short name for instance\n\t[bold]ftl[/] launch <name>")
87
- display "Spinning up FTL..."
88
89
  options.merge(options[:templates][args.first.to_sym]) if !options[:templates][args.first.to_sym].nil?
89
90
  server = launch_instance(args)
90
91
  end
@@ -94,17 +95,20 @@ module Ftl
94
95
  alias :new :launch
95
96
 
96
97
  def spot(args={})
97
- guard(args.first, "Please provide a short name for instance\n\t[bold]ftl[/] spot <name> <price>")
98
+ guard(args[0], "Please provide a short name for instance\n\t[bold]ftl[/] spot <name> <price>")
98
99
  guard(args[1], "Please provide a price for spot request\n\t[bold]ftl[/] spot <name> <price>")
99
100
  display "Spinning up FTL..."
100
101
  options.merge(options[:templates][args.first.to_sym]) if !options[:templates][args.first.to_sym].nil?
101
- options[:price] = args[1]
102
+ options[:price] = args[1] || options[:templates][args.first.to_sym][:price] || options[:price]
103
+ options.merge!(:launcher => :spot_requests)
102
104
  server = launch_instance(args)
103
105
  end
106
+ alias :request :spot
104
107
 
105
108
  def spots(args={})
106
109
  con.spot_requests.table(_headers_for(:spot_requests))
107
110
  end
111
+ alias :spot_requests :spots
108
112
 
109
113
  def cancel(args={})
110
114
  guard(args.first, "Please provide the id for the spot request to cancel.")
@@ -116,11 +120,19 @@ module Ftl
116
120
  end
117
121
  end
118
122
 
123
+ def running_instances(name)
124
+ find_instances(name).select{|i| i.state == "running" }
125
+ end
126
+
127
+ def running_instance(name)
128
+ instances = running_instances(name)
129
+ instances.first if instances
130
+ end
131
+
119
132
  def connect(args={})
120
- if match = find_instances(args.first).select{|i| i.state == "running" }.first
121
- opt_key = "-i #{options[:keys][match[:key_name]]}" unless (options[:keys].nil? || options[:keys][match[:key_name]].nil?)
122
- hostname = match[:dns_name] || match[:public_ip_address] || match[:private_ip_address]
123
- exec("ssh #{opt_key} #{options[:username]||'root'}@#{hostname}")
133
+ if server = running_instance(args.first)
134
+ # puts(ssh_command(server))
135
+ exec(ssh_command(server))
124
136
  else
125
137
  display "Typo alert! No server found!"
126
138
  end
@@ -133,34 +145,49 @@ module Ftl
133
145
  server = find_instance(args.first)
134
146
  display server
135
147
  end
148
+ alias :st :status
136
149
 
137
150
  def start(args={})
138
- display "Starting stopped instances is not implemented yet. Stay tuned true believers."
151
+ display "Bringing \"#{args.first}\" server back to life."
152
+ find_instance(args.first).start
139
153
  end
154
+ alias :run :start
140
155
 
141
156
  def stop(args={})
142
- display "Stopping running instances is not implemented yet. Stay tuned true believers."
157
+ display "Stopping \"#{args.first}\" server."
158
+ find_instance(args.first).stop
143
159
  end
160
+ alias :pause :stop
144
161
 
145
162
  def destroy(args={})
146
- if args.first.nil?
147
- display "Please provide the name (or partial name for the instance(s) you want to delete. For instance, like: ftl destroy ninja"
148
- return
163
+ guard(on_what, "Please provide the name (or partial name for the instance(s) you want to delete. For instance, like: ftl destroy ninja")
164
+ display "Spinning down FTL..."
165
+ instances = find_instances(on_what).select{|i| i.state == 'running' }
166
+ if !instances.empty?
167
+ instances.map(&:destroy)
168
+ display "Destroyed [bold]\[#{instances.map(&:id).join(', ')}\][/]"
169
+ else
170
+ display "No instances found"
149
171
  end
172
+ end
173
+ alias :d :destroy
174
+ alias :delete :destroy
175
+ alias :kill :destroy
176
+ alias :down :destroy
177
+ alias :shutdown :destroy
178
+
179
+ def terminate(args={})
180
+ guard(on_what, "Please provide the name (or partial name for the instance(s) you want to terminate. For instance, like: ftl destroy ninja")
150
181
  display "Spinning down FTL..."
151
- instances = find_instances(args.first)
152
- if instances
182
+ instances = find_instances(on_what)
183
+ if !instances.empty?
153
184
  instances.map(&:destroy)
154
- display "Terminated [bold]\[#{instances.map(&:id).join(', ')}\][/]"
185
+ display "Destroyed [bold]\[#{instances.map(&:id).join(', ')}\][/]"
155
186
  else
156
187
  display "No instances found"
157
188
  end
158
189
  end
159
- alias :d :destroy
160
- alias :delete :destroy
161
- alias :kill :destroy
162
- alias :down :destroy
163
- alias :shutdown :destroy
190
+ alias :t :terminate
164
191
 
165
192
  def info(args={})
166
193
  display find_instance(args.first)
@@ -171,11 +198,13 @@ module Ftl
171
198
  opts = [:servers] if opts.empty?
172
199
  con.send(opts.first).table(_headers_for(opts.first))
173
200
  end
174
- alias :l :list
201
+ alias :l :list
202
+ alias :ls :list
175
203
 
176
204
  def image(args={})
177
205
  Formatador.display_table(con.images.find(:id => args.first))
178
206
  end
207
+ alias :img :image
179
208
 
180
209
  # TODO: Make this better by including more details of block devices
181
210
  def images(args={})
@@ -188,14 +217,29 @@ module Ftl
188
217
  end
189
218
  puts Formatador.display_table(hashes)
190
219
  end
220
+ alias :describe_images :images
221
+
222
+ def ip_addresses
223
+ con.addresses
224
+ end
225
+
226
+ def ips(args={})
227
+ # TODO add server "name"
228
+ addrs = con.describe_addresses.body['addressesSet'] #.collect do |addr|
229
+ # addr
230
+ # end
231
+ Formatador.display_table addrs
232
+ end
233
+ alias :addresses :ips
191
234
 
192
235
  def headers(args={})
193
- display "Showing header options for #{args.first}"
194
- display con.send(args.first).first.attributes.keys
236
+ what = args.first || :servers
237
+ display "Showing header options for #{what}"
238
+ display con.send(what).first.attributes.keys
195
239
  end
196
240
 
197
241
  def server_instances(args={})
198
- @servers ||= @con.servers.all
242
+ @servers ||= (con.servers.all||[])
199
243
  end
200
244
 
201
245
  def edit(args={})
@@ -207,10 +251,45 @@ module Ftl
207
251
  puts File.open(File.dirname(__FILE__) + "/../resources/ftl.yml").read
208
252
  end
209
253
 
254
+ def command
255
+ @args[0]
256
+ end
257
+
258
+ def secondary_arguments
259
+ @args[1]
260
+ end
261
+
262
+ def on_what
263
+ secondary_arguments.first
264
+ end
265
+
266
+ def volume(args={})
267
+ arg = args.is_a?(String) ? args : on_what
268
+ display vol = con.volumes.select{|v| v.tags['Name'] == arg || v.id == arg }.first
269
+ vol
270
+ end
271
+
272
+ def execute(args={})
273
+ arg = args.is_a?(String) ? args : args[1]
274
+ server = find_instances(on_what).select{|i| i.state == 'running' }.first
275
+ puts %|#{ssh_command(server)} #{arg}|
276
+ system(%|#{ssh_command(server)} #{arg}|)
277
+ end
278
+ alias :ex :execute
279
+
210
280
  ###########################################################################
211
281
  ## private ###
212
282
  ###########################################################################
213
283
  private
284
+
285
+ def ssh_command(server)
286
+ opt_key = " -i #{options[:keys][server[:key_name]]}" unless (options[:keys].nil? || options[:keys][server[:key_name]].nil?)
287
+ hostname = server[:public_ip_address] || server[:dns_name] || server[:private_ip_address]
288
+ server_name = server.tags['Name'].to_sym
289
+ user_name = options[:templates][server_name][:username]
290
+ user_name = 'root' if user_name.nil? || user_name.length == 0
291
+ "ssh#{opt_key} #{user_name}@#{hostname}"
292
+ end
214
293
 
215
294
  def guard(arg, options={:message => "Please refer to ftl help"})
216
295
  if arg.nil?
@@ -224,7 +303,7 @@ module Ftl
224
303
  end
225
304
 
226
305
  def load_config(opts={})
227
- # TODO Make this less shitty. Such a common pattern.
306
+ # TODO So ugly, make this less shitty. Such a common pattern.
228
307
  if opts[:config]
229
308
  default_config_file = opts[:config]
230
309
  else
@@ -267,9 +346,9 @@ module Ftl
267
346
  when :volumes
268
347
  [:server_id, :id, :size, :snapshot_id, :availability_zone, :state, :"tags.Name"]
269
348
  when nil
270
- [:id, :image_id, :flavor_id, :availability_zone, :state, :"tags.Name"]
349
+ [:id, :image_id, :flavor_id, :availability_zone, :state, :created_at, :"tags.Name"]
271
350
  else
272
- [:id, :image_id, :flavor_id, :availability_zone, :state, :"tags.Name"]
351
+ [:id, :image_id, :flavor_id, :availability_zone, :state, :created_at, :"tags.Name"]
273
352
  end
274
353
  end
275
354
 
@@ -285,17 +364,35 @@ module Ftl
285
364
  def eval_action(script, args)
286
365
  # TODO Complete the script to handle multiple servers, like:
287
366
  # ftl bundle server1 server2 server3
288
- server = find_instance(args[1].first)
367
+ # server = find_instance(on_what)
368
+ server = find_instances(on_what).select{|i| i.state == 'running' }.first
369
+ eval(script, binding)
370
+ end
371
+
372
+ def eval_script(script, args)
289
373
  eval(script, binding)
290
374
  end
291
375
 
376
+ def local(cmd)
377
+ puts output = %x|#{cmd}|
378
+ output
379
+ end
380
+
381
+ # def remote(cmd)
382
+ # %x|#{ssh_command(server)} #{cmd}|
383
+ # end
384
+
292
385
  def method_missing(*args)
293
- begin
294
- method = args.first.to_sym
295
- display con.send(method).table(_headers_for(method)) if con.respond_to? method
296
- eval_action(@options[:actions][method], args) if @options[:actions][method]
386
+ method = args.first.to_sym
387
+ if con.respond_to? method
388
+ results = con.send(method)
389
+ display results.table(_headers_for(method))
390
+ elsif options[:actions][method]
391
+ eval_action(options[:actions][method], args)
392
+ elsif options[:scripts][method]
393
+ eval_script(options[:scripts][method], args)
394
+ else
297
395
  Ftl.help
298
- rescue
299
396
  end
300
397
  end
301
398
 
@@ -1,3 +1,3 @@
1
1
  module Ftl
2
- VERSION = "0.2.4"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -5,23 +5,20 @@
5
5
  ACCESS_KEY_ID:
6
6
  SECRET_ACCESS_KEY:
7
7
 
8
- :ami: ami-a29943cb # Ubuntu 12.04 LTS Precise Pangolin
9
- :username: ubuntu
10
- :instance_type: t1.micro # m1.small
11
- :user_data: |
12
- #!/bin/sh
13
- touch /root/file.touched
14
- :post_script: |
15
- :tags: {}
8
+ :scripts:
9
+ :ls: |
10
+ local("ls -alh")
11
+ local("echo '-----------'")
12
+
16
13
  :actions:
17
14
  :uptime: puts server.ssh('uptime').first.stdout
18
15
  :mount: puts server.ssh('mount').first.stdout
19
16
  :df: puts server.ssh('df -h').first.stdout
20
17
  :w: puts server.ssh('w').first.stdout
21
18
 
22
-
23
19
  :templates:
24
- :default:
20
+
21
+ :defaults: &defaults
25
22
  :ami: ami-a29943cb # Ubuntu 12.04 LTS Precise Pangolin
26
23
  :username: ubuntu
27
24
  :instance_type: m1.small
@@ -30,4 +27,9 @@ SECRET_ACCESS_KEY:
30
27
  touch /root/file.touched
31
28
  :post_script: |
32
29
 
30
+ :ninja_server:
31
+ <<: *defaults
32
+ :user_data: |
33
+ #!/bin/sh
34
+ uptime > /root/uptime.txt
33
35
 
metadata CHANGED
@@ -1,82 +1,120 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ftl
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
4
5
  prerelease:
5
- version: 0.2.4
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Matt Petty
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2012-07-15 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2012-07-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: rdoc
17
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
18
17
  none: false
19
- requirements:
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
23
22
  type: :development
24
23
  prerelease: false
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
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
27
31
  name: aruba
28
- requirement: &id002 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
29
33
  none: false
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: "0"
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
34
38
  type: :development
35
39
  prerelease: false
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
38
47
  name: rake
39
- requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
40
49
  none: false
41
- requirements:
50
+ requirements:
42
51
  - - ~>
43
- - !ruby/object:Gem::Version
52
+ - !ruby/object:Gem::Version
44
53
  version: 0.9.2
45
54
  type: :development
46
55
  prerelease: false
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.2
62
+ - !ruby/object:Gem::Dependency
49
63
  name: fog
50
- requirement: &id004 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
51
65
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: "0"
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
56
70
  type: :runtime
57
71
  prerelease: false
58
- version_requirements: *id004
59
- - !ruby/object:Gem::Dependency
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
60
79
  name: formatador
61
- requirement: &id005 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
62
81
  none: false
63
- requirements:
82
+ requirements:
64
83
  - - ~>
65
- - !ruby/object:Gem::Version
84
+ - !ruby/object:Gem::Version
66
85
  version: 0.2.2
67
86
  type: :runtime
68
87
  prerelease: false
69
- version_requirements: *id005
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.2.2
94
+ - !ruby/object:Gem::Dependency
95
+ name: tilt
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
70
110
  description: Ftl is a command line tool for Fog/AWS
71
- email:
111
+ email:
72
112
  - matt@kizmeta.com
73
- executables:
113
+ executables:
74
114
  - ftl
75
115
  extensions: []
76
-
77
116
  extra_rdoc_files: []
78
-
79
- files:
117
+ files:
80
118
  - .gitignore
81
119
  - Changelog
82
120
  - Gemfile
@@ -101,38 +139,35 @@ files:
101
139
  - test/tc_something.rb
102
140
  homepage: http://github.com/lodestone/ftl
103
141
  licenses: []
104
-
105
142
  post_install_message:
106
143
  rdoc_options: []
107
-
108
- require_paths:
144
+ require_paths:
109
145
  - lib
110
- required_ruby_version: !ruby/object:Gem::Requirement
146
+ required_ruby_version: !ruby/object:Gem::Requirement
111
147
  none: false
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- hash: -3514707693365094716
116
- segments:
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ segments:
117
153
  - 0
118
- version: "0"
119
- required_rubygems_version: !ruby/object:Gem::Requirement
154
+ hash: 2669038478733499008
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
156
  none: false
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- hash: -3514707693365094716
125
- segments:
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ segments:
126
162
  - 0
127
- version: "0"
163
+ hash: 2669038478733499008
128
164
  requirements: []
129
-
130
165
  rubyforge_project:
131
- rubygems_version: 1.8.11
166
+ rubygems_version: 1.8.24
132
167
  signing_key:
133
168
  specification_version: 3
134
169
  summary: Ftl is a command line tool for Fog/AWS
135
- test_files:
170
+ test_files:
136
171
  - features/ftl.feature
137
172
  - features/step_definitions/ftl_steps.rb
138
173
  - features/support/env.rb