pairhost 0.0.1 → 0.0.2
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/bin/pairhost +2 -168
- data/lib/pairhost/version.rb +1 -1
- data/lib/pairhost.rb +178 -1
- data/pairhost.gemspec +1 -1
- metadata +3 -5
- data/Gemfile.lock +0 -31
- data/config.yml +0 -10
data/bin/pairhost
CHANGED
@@ -1,172 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
5
|
-
require 'thor'
|
6
|
-
require 'yaml'
|
4
|
+
require 'pairhost'
|
7
5
|
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@config = YAML.load(File.open("./config.yml"))
|
11
|
-
@instance_id = File.read(File.expand_path('~/.pairhost/instance')).chomp
|
12
|
-
|
13
|
-
Fog.credentials = Fog.credentials.merge(
|
14
|
-
:private_key_path => @config['private_key_path'],
|
15
|
-
)
|
16
|
-
|
17
|
-
@connection = Fog::Compute.new(
|
18
|
-
:provider => @config['provider'],
|
19
|
-
:aws_secret_access_key => @config['aws_secret_access_key'],
|
20
|
-
:aws_access_key_id => @config['aws_access_key_id'],
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
def create
|
25
|
-
server_options = {
|
26
|
-
"tags" => {"Name" => "DevOps Dev (LK FTW)"},
|
27
|
-
"image_id" => @config['ami_id'],
|
28
|
-
"flavor_id" => @config['flavor_id'],
|
29
|
-
"key_name" => @config['key_name'],
|
30
|
-
}
|
31
|
-
|
32
|
-
puts "Provisioning..."
|
33
|
-
server = @connection.servers.create(server_options)
|
34
|
-
server.wait_for { ready? }
|
35
|
-
puts "provisioned!"
|
36
|
-
server
|
37
|
-
end
|
38
|
-
|
39
|
-
def start(server)
|
40
|
-
puts "Starting..."
|
41
|
-
server.start
|
42
|
-
server.wait_for { ready? }
|
43
|
-
puts "Started!"
|
44
|
-
end
|
45
|
-
|
46
|
-
def check_ssh(server)
|
47
|
-
# Try to ssh in every 3 seconds until
|
48
|
-
# we get a response or one minute passes
|
49
|
-
server.wait_for(60, 3) do
|
50
|
-
begin
|
51
|
-
puts "Trying to ssh..."
|
52
|
-
output = ssh('/bin/pwd')
|
53
|
-
puts output.inspect
|
54
|
-
output
|
55
|
-
rescue => e
|
56
|
-
puts "ssh failed... exception was #{e}"
|
57
|
-
false
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def fetch_server
|
63
|
-
@connection.servers.get(@instance_id) if @instance_id
|
64
|
-
end
|
65
|
-
|
66
|
-
def display_status(server)
|
67
|
-
puts "#{server.id}: #{server.tags['Name']}"
|
68
|
-
puts server.state
|
69
|
-
puts server.dns_name if server.dns_name
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
class PairhostCLI < Thor
|
74
|
-
desc "ssh", "SSH to your pairhost"
|
75
|
-
def ssh
|
76
|
-
server = Pairhost.new.fetch_server
|
77
|
-
exec "ssh -A -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=QUIET pair@#{server.reload.dns_name}"
|
78
|
-
end
|
79
|
-
|
80
|
-
desc "status", "Print the status of your pairhost"
|
81
|
-
def status
|
82
|
-
ph = Pairhost.new
|
83
|
-
server = ph.fetch_server
|
84
|
-
ph.display_status(server)
|
85
|
-
end
|
86
|
-
|
87
|
-
map "stop" => :shutdown
|
88
|
-
map "halt" => :shutdown
|
89
|
-
|
90
|
-
desc "shutdown", "Stop your pairhost"
|
91
|
-
def shutdown
|
92
|
-
ph = Pairhost.new
|
93
|
-
server = ph.fetch_server
|
94
|
-
puts "Shutting down..."
|
95
|
-
server.stop
|
96
|
-
server.wait_for { state == "stopped" }
|
97
|
-
puts "shutdown!"
|
98
|
-
end
|
99
|
-
|
100
|
-
desc "attach", "Start using an existing pairhost given its EC2 instance ID"
|
101
|
-
def attach
|
102
|
-
puts "coming soon..."
|
103
|
-
end
|
104
|
-
|
105
|
-
# TODO: replace with "up" (which does a "create" or a "start" as appropriate)
|
106
|
-
# create asks for a name, but gives you a default based on the $CWD and git initials, if any
|
107
|
-
desc "up", "Create a new pairhost or start your stopped pairhost"
|
108
|
-
def up
|
109
|
-
ph = Pairhost.new
|
110
|
-
server = ph.fetch_server
|
111
|
-
|
112
|
-
if server
|
113
|
-
ph.start(server)
|
114
|
-
else
|
115
|
-
server = ph.create
|
116
|
-
end
|
117
|
-
|
118
|
-
ph.display_status(server)
|
119
|
-
end
|
120
|
-
|
121
|
-
desc "destroy", "Terminate your pairhost"
|
122
|
-
def destroy
|
123
|
-
server = fetch_server
|
124
|
-
puts "Destroying..."
|
125
|
-
server.destroy
|
126
|
-
server.wait_for { state == "terminated" }
|
127
|
-
puts "destroyed!"
|
128
|
-
end
|
129
|
-
|
130
|
-
desc "list", "List all instances on your EC2 account"
|
131
|
-
def list
|
132
|
-
@config[:pairhost].connection.servers.each do |server|
|
133
|
-
puts server.tags['Name']
|
134
|
-
puts server.inspect
|
135
|
-
puts
|
136
|
-
puts
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
desc "initials", "DEBUG: just a test task for getting the current git initials"
|
141
|
-
def initials
|
142
|
-
initials = `git config user.initials`.chomp.split("/").map(&:upcase).join(" ")
|
143
|
-
puts initials.inspect
|
144
|
-
end
|
145
|
-
|
146
|
-
desc "init", "Setup your ~/.pairhost directory with default config"
|
147
|
-
def init
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
=begin
|
153
|
-
vagrant commands:
|
154
|
-
box --> ignore?
|
155
|
-
destroy
|
156
|
-
gem --> ignore
|
157
|
-
halt
|
158
|
-
init --> ignore
|
159
|
-
package --> ignore
|
160
|
-
provision
|
161
|
-
reload
|
162
|
-
resume
|
163
|
-
ssh
|
164
|
-
ssh-config --> ignore?
|
165
|
-
status
|
166
|
-
suspend
|
167
|
-
up
|
168
|
-
=end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
PairhostCLI.start
|
6
|
+
Pairhost::CLI.start
|
data/lib/pairhost/version.rb
CHANGED
data/lib/pairhost.rb
CHANGED
@@ -1,5 +1,182 @@
|
|
1
1
|
require "pairhost/version"
|
2
|
+
require 'fog'
|
3
|
+
require 'thor'
|
4
|
+
require 'yaml'
|
5
|
+
require 'fileutils'
|
2
6
|
|
3
7
|
module Pairhost
|
4
|
-
|
8
|
+
def self.config_file
|
9
|
+
@config_file ||= File.expand_path('~/.pairhost/config.yml')
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.config
|
13
|
+
@config ||= begin
|
14
|
+
unless File.exists?(config_file)
|
15
|
+
abort "No pairhost config found. First run 'pairhost init'."
|
16
|
+
end
|
17
|
+
YAML.load_file(config_file)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.instance_id
|
22
|
+
@instance_id ||= File.read(File.expand_path('~/.pairhost/instance')).chomp
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.connection
|
26
|
+
return @connection if @connection
|
27
|
+
|
28
|
+
Fog.credentials = Fog.credentials.merge(
|
29
|
+
:private_key_path => config['private_key_path'],
|
30
|
+
)
|
31
|
+
|
32
|
+
@connection = Fog::Compute.new(
|
33
|
+
:provider => config['provider'],
|
34
|
+
:aws_secret_access_key => config['aws_secret_access_key'],
|
35
|
+
:aws_access_key_id => config['aws_access_key_id'],
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.create(name)
|
40
|
+
server_options = {
|
41
|
+
"tags" => {"Name" => name,
|
42
|
+
"Created-By-Pairhost-Gem" => VERSION},
|
43
|
+
"image_id" => config['ami_id'],
|
44
|
+
"flavor_id" => config['flavor_id'],
|
45
|
+
"key_name" => config['key_name'],
|
46
|
+
}
|
47
|
+
|
48
|
+
server = connection.servers.create(server_options)
|
49
|
+
server.wait_for { ready? }
|
50
|
+
|
51
|
+
@instance_id = server.id
|
52
|
+
write_instance_id(@instance_id)
|
53
|
+
|
54
|
+
server
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.write_instance_id(instance_id)
|
58
|
+
File.open(File.expand_path('~/.pairhost/instance'), "w") do |f|
|
59
|
+
f.write(instance_id)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.start(server)
|
64
|
+
server.start
|
65
|
+
server.wait_for { ready? }
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.stop(server)
|
69
|
+
server.stop
|
70
|
+
server.wait_for { state == "stopped" }
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.fetch
|
74
|
+
connection.servers.get(instance_id) if instance_id
|
75
|
+
end
|
76
|
+
|
77
|
+
class CLI < Thor
|
78
|
+
include Thor::Actions
|
79
|
+
|
80
|
+
desc "ssh", "SSH to your pairhost"
|
81
|
+
def ssh
|
82
|
+
server = Pairhost.fetch
|
83
|
+
exec "ssh -A -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=QUIET pair@#{server.dns_name}"
|
84
|
+
end
|
85
|
+
|
86
|
+
desc "status", "Print the status of your pairhost"
|
87
|
+
def status
|
88
|
+
server = Pairhost.fetch
|
89
|
+
puts "#{server.id}: #{server.tags['Name']}"
|
90
|
+
puts "State: #{server.state}"
|
91
|
+
puts server.dns_name if server.dns_name
|
92
|
+
end
|
93
|
+
|
94
|
+
map "start" => :resume
|
95
|
+
|
96
|
+
desc "resume", "Start a stopped pairhost"
|
97
|
+
def resume
|
98
|
+
server = Pairhost.fetch
|
99
|
+
puts "Starting..."
|
100
|
+
Pairhost.start(server.reload)
|
101
|
+
puts "started!"
|
102
|
+
|
103
|
+
invoke :status
|
104
|
+
end
|
105
|
+
|
106
|
+
desc "create", "Provision a new pairhost; all future commands affect this pairhost"
|
107
|
+
def create
|
108
|
+
initials = `git config user.initials`.chomp.split("/").map(&:upcase).join(" ")
|
109
|
+
default_name = "something1 #{initials}"
|
110
|
+
name = ask_with_default("What to name your pairhost? [#{default_name}]", default_name)
|
111
|
+
puts "Name will be: #{name}"
|
112
|
+
puts "Provisioning..."
|
113
|
+
# server = Pairhost.create(name)
|
114
|
+
# puts "provisioning!"
|
115
|
+
# invoke :status
|
116
|
+
end
|
117
|
+
|
118
|
+
desc "up", "Create a new pairhost or start your stopped pairhost"
|
119
|
+
def up
|
120
|
+
server = Pairhost.fetch
|
121
|
+
|
122
|
+
if server
|
123
|
+
invoke :resume
|
124
|
+
else
|
125
|
+
invoke :create
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
map "halt" => :stop
|
130
|
+
map "shutdown" => :stop
|
131
|
+
map "suspend" => :stop
|
132
|
+
|
133
|
+
desc "stop", "Stop your pairhost"
|
134
|
+
def stop
|
135
|
+
server = Pairhost.fetch
|
136
|
+
puts "Shutting down..."
|
137
|
+
Pairhost.stop(server)
|
138
|
+
puts "shutdown!"
|
139
|
+
end
|
140
|
+
|
141
|
+
desc "attach", "All future commands affect this pairhost"
|
142
|
+
def attach
|
143
|
+
instance_id = ask("EC2 Instance?")
|
144
|
+
Pairhost.write_instance_id(instance_id)
|
145
|
+
invoke :status
|
146
|
+
end
|
147
|
+
|
148
|
+
map "terminate" => :destroy
|
149
|
+
|
150
|
+
desc "destroy", "Terminate your pairhost"
|
151
|
+
def destroy
|
152
|
+
server = Pairhost.fetch
|
153
|
+
confirm = ask("Type 'yes' to confirm deleting '#{server.tags['Name']}'.\n>")
|
154
|
+
|
155
|
+
return unless confirm == "yes"
|
156
|
+
|
157
|
+
puts "Destroying..."
|
158
|
+
server.destroy
|
159
|
+
server.wait_for { state == "terminated" }
|
160
|
+
puts "destroyed!"
|
161
|
+
end
|
162
|
+
|
163
|
+
desc "init", "Setup your ~/.pairhost directory with default config"
|
164
|
+
def init
|
165
|
+
FileUtils.mkdir_p File.dirname(Pairhost.config_file)
|
166
|
+
FileUtils.cp(File.dirname(__FILE__) + '/../config.example.yml', Pairhost.config_file)
|
167
|
+
end
|
168
|
+
|
169
|
+
desc "provision", "Freshen the Chef recipes"
|
170
|
+
def provision
|
171
|
+
puts "coming soon..."
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
def ask_with_default(question, default)
|
177
|
+
answer = ask(question)
|
178
|
+
answer = answer.strip.empty? ? default : answer
|
179
|
+
answer
|
180
|
+
end
|
181
|
+
end
|
5
182
|
end
|
data/pairhost.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["larry@hickorywind.org"]
|
10
10
|
s.homepage = "http://www.github.com/karnowski/pairhost"
|
11
11
|
s.summary = %q{Automate creation of Relevance pairhost EC2 instances.}
|
12
|
-
s.description = %q{A Vagrant-like command line interface for creating, managing, and using EC2
|
12
|
+
s.description = %q{A Vagrant-like command line interface for creating, managing, and using EC2 instances for remote pairing.}
|
13
13
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pairhost
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 0.14.6
|
46
46
|
description: A Vagrant-like command line interface for creating, managing, and using
|
47
|
-
EC2
|
47
|
+
EC2 instances for remote pairing.
|
48
48
|
email:
|
49
49
|
- larry@hickorywind.org
|
50
50
|
executables:
|
@@ -54,12 +54,10 @@ extra_rdoc_files: []
|
|
54
54
|
files:
|
55
55
|
- .gitignore
|
56
56
|
- Gemfile
|
57
|
-
- Gemfile.lock
|
58
57
|
- README.md
|
59
58
|
- Rakefile
|
60
59
|
- bin/pairhost
|
61
60
|
- config.example.yml
|
62
|
-
- config.yml
|
63
61
|
- lib/pairhost.rb
|
64
62
|
- lib/pairhost/version.rb
|
65
63
|
- pairhost.gemspec
|
data/Gemfile.lock
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
builder (3.0.0)
|
5
|
-
excon (0.9.6)
|
6
|
-
fog (1.1.2)
|
7
|
-
builder
|
8
|
-
excon (~> 0.9.0)
|
9
|
-
formatador (~> 0.2.0)
|
10
|
-
mime-types
|
11
|
-
multi_json (~> 1.0.3)
|
12
|
-
net-scp (~> 1.0.4)
|
13
|
-
net-ssh (>= 2.1.3)
|
14
|
-
nokogiri (~> 1.5.0)
|
15
|
-
ruby-hmac
|
16
|
-
formatador (0.2.1)
|
17
|
-
mime-types (1.17.2)
|
18
|
-
multi_json (1.0.4)
|
19
|
-
net-scp (1.0.4)
|
20
|
-
net-ssh (>= 1.99.1)
|
21
|
-
net-ssh (2.3.0)
|
22
|
-
nokogiri (1.5.1)
|
23
|
-
ruby-hmac (0.4.0)
|
24
|
-
thor (0.14.6)
|
25
|
-
|
26
|
-
PLATFORMS
|
27
|
-
ruby
|
28
|
-
|
29
|
-
DEPENDENCIES
|
30
|
-
fog (= 1.1.2)
|
31
|
-
thor (= 0.14.6)
|
data/config.yml
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
provider: 'AWS'
|
2
|
-
aws_secret_access_key: 'aOWCyMXgpFd452aBh4BRyPGkR/RtQ9G0qQX/5aQV'
|
3
|
-
aws_access_key_id: 'AKIAIQZWXGD2S56W2MMQ'
|
4
|
-
|
5
|
-
# 608860329496/Ubuntu 11.04 64-bit Pairhost (2011-10-26)
|
6
|
-
ami_id: 'ami-9360affa'
|
7
|
-
flavor_id: 'm1.large'
|
8
|
-
|
9
|
-
key_name: 'relevance_aws'
|
10
|
-
private_key_path: '~/.ssh/relevance_aws/relevance_aws.pem'
|