ftl 0.0.1

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gems ADDED
@@ -0,0 +1,6 @@
1
+ sinatra --version 0.9.6
2
+ activesupport --version 2.3.5
3
+ aws
4
+ httparty
5
+
6
+
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Matt Petty
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = FTL: Faster Than Light Pair Programing Server
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Matt Petty matt@kizmeta.com. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ftl"
8
+ gem.summary = %Q{Easily launch ec2 instances for pair programming}
9
+ gem.description = %Q{FTL spins up and down Amazon EC2 instances for pair programming}
10
+ gem.email = "matt@kizmeta.com"
11
+ gem.homepage = "http://github.com/lodestone/ftl"
12
+ gem.authors = ["Matt Petty"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "ftl #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/TODO ADDED
@@ -0,0 +1,24 @@
1
+ TESTS!!!
2
+
3
+
4
+ Server:
5
+ HTTP auth (read from config/ftl.yml)
6
+
7
+
8
+
9
+ Start up script:
10
+ rvm
11
+ need dev user
12
+ .dotfiles:
13
+ get latest .vim
14
+ get latest .screenrc
15
+ get latest .git config
16
+ git co latest repos
17
+ make sure login starts screen properly with follow-the-leader setup
18
+ make sure mysql/postgres is started
19
+
20
+
21
+ LATER:
22
+ set ASCII art login prompt
23
+ add hashrocket git pairing switcher thingy
24
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/ftl ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'ftl'
4
+ FTL::Client.new(ARGV)
5
+
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require 'lib/ftl/server'
2
+ run FTL::Server
3
+
data/ftl.gemspec ADDED
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ftl}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Matt Petty"]
12
+ s.date = %q{2010-07-21}
13
+ s.default_executable = %q{ftl}
14
+ s.description = %q{FTL spins up and down Amazon EC2 instances for pair programming}
15
+ s.email = %q{matt@kizmeta.com}
16
+ s.executables = ["ftl"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc",
20
+ "TODO"
21
+ ]
22
+ s.files = [
23
+ ".document",
24
+ ".gems",
25
+ ".gitignore",
26
+ "LICENSE",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "TODO",
30
+ "VERSION",
31
+ "bin/ftl",
32
+ "config.ru",
33
+ "ftl.gemspec",
34
+ "lib/ftl.rb",
35
+ "lib/ftl/client.rb",
36
+ "lib/ftl/server.rb",
37
+ "test/helper.rb",
38
+ "test/test_ftl.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/lodestone/ftl}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.6}
44
+ s.summary = %q{Easily launch ec2 instances for pair programming}
45
+ s.test_files = [
46
+ "test/helper.rb",
47
+ "test/test_ftl.rb"
48
+ ]
49
+
50
+ if s.respond_to? :specification_version then
51
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
+ s.specification_version = 3
53
+
54
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
56
+ else
57
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
61
+ end
62
+ end
63
+
data/lib/ftl.rb ADDED
@@ -0,0 +1 @@
1
+ require 'ftl/client'
data/lib/ftl/client.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'httparty'
2
+ require 'json'
3
+
4
+ module FTL
5
+
6
+ class Client
7
+
8
+ include HTTParty
9
+
10
+ CONFIG = YAML.load_file(ENV['HOME']+'/.ftl/ftl.yml')
11
+ ACCESS_KEY_ID = CONFIG['ACCESS_KEY_ID']
12
+ SECRET_ACCESS_KEY = CONFIG['SECRET_ACCESS_KEY']
13
+
14
+ base_uri CONFIG['server']
15
+ format :json
16
+
17
+ def initialize(args={})
18
+ send(args.reverse!.pop, args)
19
+ end
20
+
21
+ def start(args={})
22
+ if args.first.nil?
23
+ puts "Please provide a short name for instance, like: ftl start ninjaserver"
24
+ return
25
+ end
26
+ puts "Spinning up FTL..."
27
+ self.class.post('/machines', :body => '', :query => {:name => args.first, :ami => CONFIG['ami']})
28
+ end
29
+
30
+ def connect(args={})
31
+ response = self.class.get('/machines')
32
+ if response.length == 0
33
+ puts "No machines running. try: ftl start <servername>"
34
+ elsif response.length == 1
35
+ server = response.first
36
+ elsif response.length > 1
37
+ if args.first.nil?
38
+ puts "Please provide the name (or partial name for the instance(s) you want to delete. For instance, like: ftl destroy ninja"
39
+ end
40
+ server = response.detect{|r| r['name'][args.first] }
41
+ if server.nil?
42
+ puts "Couldn't find that server name. try: ftl list"
43
+ end
44
+ end
45
+ exec("ssh dev@#{server['dns_name']}") if server['dns_name']
46
+ end
47
+
48
+ def destroy(args={})
49
+ if args.first.nil?
50
+ puts "Please provide the name (or partial name for the instance(s) you want to delete. For instance, like: ftl destroy ninja"
51
+ return
52
+ end
53
+ puts "Spinning down FTL..."
54
+ response = self.class.delete('/machines', :query => {:name => args.first}, :body => {:name => args.first})
55
+ puts response['message']
56
+ end
57
+
58
+ def list(args={})
59
+ response = self.class.get('/machines')
60
+ column_widths = {'#' => 4}
61
+ if response.blank?
62
+ puts "No machines are running"
63
+ return
64
+ end
65
+ keys = response.first.keys
66
+ display_keys = ['#'] + keys
67
+ separator = ' |'
68
+
69
+
70
+ keys.each {|r|
71
+ widths = [r.length + separator.length]
72
+ widths = widths + response.collect {|pm|
73
+ # WOW right_aws sucks. Why is everything an array. BS
74
+ pm[r].first.length + separator.length
75
+ }
76
+ column_widths[r] = widths.max
77
+ }
78
+
79
+ # Headers
80
+ display_keys.sort.each do |key|
81
+ print key.rjust(column_widths[key])
82
+ print separator
83
+ end
84
+ print "\n"
85
+
86
+ # Machines
87
+ response.each_with_index do |r,idx|
88
+ r['#'] = "#{idx+1}"
89
+ display_keys.sort.each do |key|
90
+ value = r[key].nil? ? '-' : r[key].first
91
+ print value.rjust(column_widths[key])
92
+ print separator
93
+ end
94
+ print "\n"
95
+ end
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+
102
+ # TODO:
103
+ # Server:
104
+ # establish connection
105
+ # read config (what AMI)
106
+ # list available pairing instances
107
+ # start up instance
108
+ # kill instance
109
+ #
110
+ # Client
111
+ # list available pairing instances (via server call)
112
+ # create new instance
113
+ # connect to new instance
114
+ # destroy instance
data/lib/ftl/server.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'sinatra'
2
+ require 'active_support'
3
+ require 'right_aws'
4
+ require 'sdb/active_sdb'
5
+ require 'json'
6
+ # require 'fog'
7
+ # ENV["FOG_RC"] = Will need this if we switch to Fog
8
+
9
+ class PairingMachine < Aws::ActiveSdb::Base
10
+ end
11
+
12
+ module FTL
13
+
14
+ class Server < Sinatra::Base
15
+
16
+ ACCESS_KEY_ID = ENV['ACCESS_KEY_ID'] || YAML.load_file(ENV['HOME']+'/.ftl/ftl.yml')['ACCESS_KEY_ID']
17
+ SECRET_ACCESS_KEY = ENV['SECRET_ACCESS_KEY'] || YAML.load_file(ENV['HOME']+'/.ftl/ftl.yml')['SECRET_ACCESS_KEY']
18
+
19
+ before do
20
+ Aws::ActiveSdb.establish_connection(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
21
+ PairingMachine.create_domain # Raises no error if it already exists, but blows up if it doesn't
22
+ end
23
+
24
+ get '/machines' do
25
+ # List the machines
26
+ pms = PairingMachine.find(:all)
27
+ ec2 = Aws::Ec2.new(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
28
+ pms.each do |pm|
29
+ i = ec2.describe_instances(pm.attributes['aws_instance_id'])[0]
30
+ pm[:dns_name] = i[:dns_name]
31
+ pm.save
32
+ end
33
+ pms.collect{|pm| pm.attributes }.to_json
34
+ end
35
+
36
+ post '/machines' do
37
+ # Create new machine
38
+ return "Need to name this machine" unless params[:name]
39
+ return "Please provide an ami" unless params[:ami]
40
+ pm = PairingMachine.new(params)
41
+ pm[:instance_type] ||= 'm1.small'
42
+ ec2 = Aws::Ec2.new(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
43
+ i = ec2.launch_instances(params[:ami], :user_data => "#!/", :instance_type => pm[:instance_type])[0]
44
+ pm[:aws_instance_id] = i[:aws_instance_id]
45
+ pm[:dns_name] = i[:dns_name]
46
+ pm.save
47
+ pm.attributes.to_json
48
+ end
49
+
50
+ delete '/machines' do
51
+ # Destroy the machine by short name
52
+ pms = PairingMachine.find(:all)
53
+ pms = pms.select{|pm| pm.attributes['name'].first[params['name']] }
54
+ return "{message: \"Provide the name of the machine(s) to be terminated\"}" if params['name'].nil? || pms.blank?
55
+ ec2 = Aws::Ec2.new(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
56
+ instances = pms.collect{|pm| pm.attributes['aws_instance_id'].first }
57
+ ec2.terminate_instances(instances)
58
+ pms.each {|pm|
59
+ pm.delete
60
+ }
61
+ "{message: \"Shutdown machines matching '#{params['name']}'\"}"
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'ftl'
8
+
9
+ class Test::Unit::TestCase
10
+ end
data/test/test_ftl.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestFtl < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ftl
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Matt Petty
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-07-21 00:00:00 -05:00
18
+ default_executable: ftl
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thoughtbot-shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ description: FTL spins up and down Amazon EC2 instances for pair programming
33
+ email: matt@kizmeta.com
34
+ executables:
35
+ - ftl
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - LICENSE
40
+ - README.rdoc
41
+ - TODO
42
+ files:
43
+ - .document
44
+ - .gems
45
+ - .gitignore
46
+ - LICENSE
47
+ - README.rdoc
48
+ - Rakefile
49
+ - TODO
50
+ - VERSION
51
+ - bin/ftl
52
+ - config.ru
53
+ - ftl.gemspec
54
+ - lib/ftl.rb
55
+ - lib/ftl/client.rb
56
+ - lib/ftl/server.rb
57
+ - test/helper.rb
58
+ - test/test_ftl.rb
59
+ has_rdoc: true
60
+ homepage: http://github.com/lodestone/ftl
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.6
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Easily launch ec2 instances for pair programming
89
+ test_files:
90
+ - test/helper.rb
91
+ - test/test_ftl.rb