judo 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -2
- data/VERSION +1 -1
- data/bin/judo +102 -212
- data/lib/judo.rb +18 -0
- data/lib/judo/base.rb +199 -0
- data/lib/judo/commandline_helpers.rb +151 -0
- data/lib/judo/config.rb +133 -0
- data/lib/judo/group.rb +221 -0
- data/lib/judo/server.rb +513 -0
- data/lib/judo/setup.rb +114 -0
- data/spec/base.rb +1 -1
- data/spec/base_spec.rb +9 -0
- metadata +16 -26
- data/lib/all.rb +0 -12
- data/lib/config.rb +0 -105
- data/lib/group.rb +0 -185
- data/lib/server.rb +0 -491
- data/lib/setup.rb +0 -114
data/lib/judo/setup.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
module Judo
|
2
|
+
class Setup
|
3
|
+
def default_config
|
4
|
+
<<DEFAULT
|
5
|
+
{
|
6
|
+
"key_name":"#{@keypair}",
|
7
|
+
"instance_size":"m1.small",
|
8
|
+
"ami32":"ami-bb709dd2", // public ubuntu 9.10 ami - 32 bit
|
9
|
+
"ami64":"ami-55739e3c", // public ubuntu 9.10 ami - 64 bit
|
10
|
+
"user":"ubuntu",
|
11
|
+
"security_group":"judo",
|
12
|
+
"availability_zone":"us-east-1d"
|
13
|
+
}
|
14
|
+
DEFAULT
|
15
|
+
end
|
16
|
+
|
17
|
+
def getenv(key)
|
18
|
+
printf "Looking in your environment for #{key}..."
|
19
|
+
printf "found!" if ENV[key]
|
20
|
+
printf "\n"
|
21
|
+
ENV[key]
|
22
|
+
end
|
23
|
+
|
24
|
+
def request(query, default = "")
|
25
|
+
printf "#{query} ['#{default}']: "
|
26
|
+
input = STDIN.readline.strip
|
27
|
+
input.empty? and default or input
|
28
|
+
end
|
29
|
+
|
30
|
+
def check_setup
|
31
|
+
abort "you are already inside a judo repository" if Judo::Config.find_judo_dir(Dir.pwd)
|
32
|
+
abort "./.git not found - judo configurations must be kept in a git repo. type 'git init' to setup the git repo." unless File.exists? "./.git"
|
33
|
+
end
|
34
|
+
|
35
|
+
def init
|
36
|
+
check_setup
|
37
|
+
@aws_access_id ||= getenv('AWS_ACCESS_KEY_ID')
|
38
|
+
@aws_access_id ||= getenv('AMAZON_ACCESS_KEY_ID')
|
39
|
+
@aws_secret_key ||= getenv('AWS_SECRET_ACCESS_KEY')
|
40
|
+
@aws_secret_key ||= getenv('AMAZON_SECRET_ACCESS_KEY')
|
41
|
+
@s3_bucket ||= getenv('JUDO_S3_BUCKET')
|
42
|
+
@s3_bucket ||= "judo_#{rand(2**64).to_s(36)}"
|
43
|
+
begin
|
44
|
+
@aws_access_id = request("Please enter your AWS access key", @aws_access_id)
|
45
|
+
@aws_secret_key = request("Please enter your AWS secret key" , @aws_secret_key)
|
46
|
+
@s3_bucket = request("Please enter an S3 bucket to use", @s3_bucket)
|
47
|
+
|
48
|
+
setup_default_server_group
|
49
|
+
setup_default_security_group
|
50
|
+
setup_bucket
|
51
|
+
setup_db
|
52
|
+
setup_judo_config
|
53
|
+
|
54
|
+
rescue *[Interrupt, EOFError]
|
55
|
+
puts "\nGoodbye!"
|
56
|
+
exit(0)
|
57
|
+
rescue Object => e
|
58
|
+
puts "There was an error: #{e.class}:#{e.message}"
|
59
|
+
puts "Try again or hit CTRL-C"
|
60
|
+
retry
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def setup_db
|
65
|
+
puts "Trying to connect to SimpleDB with #{@aws_access_id}"
|
66
|
+
sdb.create_domain("judo_servers")
|
67
|
+
sdb.create_domain("judo_config")
|
68
|
+
olddb = sdb.get_attributes("judo_config", "judo")[:attributes]["dbversion"]
|
69
|
+
abort "There is an existing judo database of a newer version - upgrade judo and try again" if olddb and olddb.first.to_i > Judo::Config.db_version
|
70
|
+
sdb.put_attributes("judo_config", "judo", { "dbversion" => Judo::Config.db_version }, :replace)
|
71
|
+
end
|
72
|
+
|
73
|
+
def setup_default_security_group
|
74
|
+
begin
|
75
|
+
ec2.create_security_group('judo', 'Judo')
|
76
|
+
ec2.authorize_security_group_IP_ingress("judo", 22, 22,'tcp','0.0.0.0/0')
|
77
|
+
rescue Aws::AwsError => e
|
78
|
+
raise unless e.message =~ /InvalidGroup.Duplicate/
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def setup_bucket
|
83
|
+
puts "setting up an s3 bucket"
|
84
|
+
Aws::S3.new(@aws_access_id, @aws_secret_key, :logger => Logger.new(nil)).bucket(@s3_bucket, true)
|
85
|
+
end
|
86
|
+
|
87
|
+
def setup_default_server_group
|
88
|
+
puts "Setting up default group and keypair"
|
89
|
+
system "mkdir -p default/keypairs"
|
90
|
+
|
91
|
+
@keypair = "judo#{ec2.describe_key_pairs.map { |k| k[:aws_key_name] }.map { |k| k =~ /^judo(\d*)/; $1.to_i }.sort.last.to_i + 1}"
|
92
|
+
material = ec2.create_key_pair(@keypair)[:aws_material]
|
93
|
+
|
94
|
+
File.open("default/keypairs/#{@keypair}.pem", 'w') { |f| f.write material }
|
95
|
+
File.chmod 0600, "default/keypairs/#{@keypair}.pem"
|
96
|
+
File.open("default/config.json","w") { |f| f.write default_config }
|
97
|
+
end
|
98
|
+
|
99
|
+
def setup_judo_config
|
100
|
+
puts "setting up an .judo/config.yml"
|
101
|
+
system "mkdir .judo"
|
102
|
+
File.open(".judo/config.yml","w") { |f| f.write({ "access_id" => @aws_access_id, "access_secret" => @aws_secret_key, "s3_bucket" => @s3_bucket }.to_yaml) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def ec2
|
106
|
+
@ec2 ||= Judo::Config.get_ec2(@aws_access_id, @aws_secret_key)
|
107
|
+
end
|
108
|
+
|
109
|
+
def sdb
|
110
|
+
@sdb ||= Judo::Config.get_sdb(@aws_access_id, @aws_secret_key)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
data/spec/base.rb
CHANGED
data/spec/base_spec.rb
ADDED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.9
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Orion Henry
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-04-08 00:00:00 -04:00
|
18
18
|
default_executable: judo
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -27,28 +27,14 @@ dependencies:
|
|
27
27
|
segments:
|
28
28
|
- 2
|
29
29
|
- 3
|
30
|
-
-
|
31
|
-
version: 2.3.
|
30
|
+
- 5
|
31
|
+
version: 2.3.5
|
32
32
|
type: :runtime
|
33
33
|
version_requirements: *id001
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: thor
|
36
|
-
prerelease: false
|
37
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 0
|
43
|
-
- 13
|
44
|
-
- 4
|
45
|
-
version: 0.13.4
|
46
|
-
type: :runtime
|
47
|
-
version_requirements: *id002
|
48
34
|
- !ruby/object:Gem::Dependency
|
49
35
|
name: json
|
50
36
|
prerelease: false
|
51
|
-
requirement: &
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
52
38
|
requirements:
|
53
39
|
- - ">="
|
54
40
|
- !ruby/object:Gem::Version
|
@@ -56,7 +42,7 @@ dependencies:
|
|
56
42
|
- 0
|
57
43
|
version: "0"
|
58
44
|
type: :runtime
|
59
|
-
version_requirements: *
|
45
|
+
version_requirements: *id002
|
60
46
|
description: The gentle way to manage and control ec2 instances
|
61
47
|
email: orion@heroku.com
|
62
48
|
executables:
|
@@ -70,12 +56,15 @@ files:
|
|
70
56
|
- Rakefile
|
71
57
|
- VERSION
|
72
58
|
- bin/judo
|
73
|
-
- lib/
|
74
|
-
- lib/
|
75
|
-
- lib/
|
76
|
-
- lib/
|
77
|
-
- lib/
|
59
|
+
- lib/judo.rb
|
60
|
+
- lib/judo/base.rb
|
61
|
+
- lib/judo/commandline_helpers.rb
|
62
|
+
- lib/judo/config.rb
|
63
|
+
- lib/judo/group.rb
|
64
|
+
- lib/judo/server.rb
|
65
|
+
- lib/judo/setup.rb
|
78
66
|
- spec/base.rb
|
67
|
+
- spec/base_spec.rb
|
79
68
|
- spec/server_spec.rb
|
80
69
|
has_rdoc: true
|
81
70
|
homepage: http://github.com/orionz/judo
|
@@ -109,4 +98,5 @@ specification_version: 3
|
|
109
98
|
summary: The gentle way to manage and control ec2 instances
|
110
99
|
test_files:
|
111
100
|
- spec/base.rb
|
101
|
+
- spec/base_spec.rb
|
112
102
|
- spec/server_spec.rb
|
data/lib/all.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'socket'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'right_aws'
|
7
|
-
require 'json'
|
8
|
-
|
9
|
-
require File.dirname(__FILE__) + '/config'
|
10
|
-
require File.dirname(__FILE__) + '/group'
|
11
|
-
require File.dirname(__FILE__) + '/server'
|
12
|
-
require File.dirname(__FILE__) + '/setup'
|
data/lib/config.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
module Judo
|
2
|
-
module Config
|
3
|
-
extend self
|
4
|
-
|
5
|
-
def method_missing?(method)
|
6
|
-
end
|
7
|
-
|
8
|
-
def db_version
|
9
|
-
1
|
10
|
-
end
|
11
|
-
|
12
|
-
def get_db_version
|
13
|
-
version = @sdb.get_attributes("judo_config", "judo")[:attributes]["dbversion"]
|
14
|
-
version and version.first.to_i or db_version
|
15
|
-
end
|
16
|
-
|
17
|
-
def check_version
|
18
|
-
abort "judo db is newer than the current gem - upgrade judo and try again" if get_db_version > db_version
|
19
|
-
end
|
20
|
-
|
21
|
-
def repo_dir
|
22
|
-
judo_config["repo"] || File.dirname(judo_dir)
|
23
|
-
end
|
24
|
-
|
25
|
-
def access_id
|
26
|
-
judo_config["access_id"]
|
27
|
-
end
|
28
|
-
|
29
|
-
def access_secret
|
30
|
-
judo_config["access_secret"]
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_ec2(aws_id, aws_key)
|
34
|
-
Aws::Ec2.new(aws_id, aws_key, :logger => Logger.new(nil))
|
35
|
-
end
|
36
|
-
|
37
|
-
def ec2
|
38
|
-
@ec2 ||= get_ec2(access_id, access_secret)
|
39
|
-
end
|
40
|
-
|
41
|
-
# def create_security_group
|
42
|
-
# ## EC2 create_security_group
|
43
|
-
# ec2.create_security_group('judo', 'Judo')
|
44
|
-
# ## EC2 authorize_security_group
|
45
|
-
# ec2.authorize_security_group_IP_ingress("judo", 22, 22,'tcp','0.0.0.0/0')
|
46
|
-
# rescue Aws::AwsError
|
47
|
-
# end
|
48
|
-
|
49
|
-
def judo_config
|
50
|
-
@config ||= read_judo_config
|
51
|
-
end
|
52
|
-
|
53
|
-
def judo_config_file
|
54
|
-
"#{judo_dir}/config.yml"
|
55
|
-
end
|
56
|
-
|
57
|
-
def judo_dir
|
58
|
-
@judo_dir ||= find_judo_dir(Dir.pwd) || abort("fatal: Not a judo repository (or any of the parent directories): .judo\nrun commands from the judo repository or type 'judo init' to setup the current directory as a new judo repository")
|
59
|
-
end
|
60
|
-
|
61
|
-
def find_judo_dir(check)
|
62
|
-
if check == "/"
|
63
|
-
if File.exists?("#{ENV['HOME']}/.judo")
|
64
|
-
"#{ENV['HOME']}/.judo"
|
65
|
-
else
|
66
|
-
nil
|
67
|
-
end
|
68
|
-
else
|
69
|
-
File.exists?(check + "/.judo") ? check + "/.judo" : find_judo_dir(File.dirname(check))
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def read_judo_config
|
74
|
-
YAML.load File.read(judo_config_file)
|
75
|
-
rescue Errno::ENOENT
|
76
|
-
{}
|
77
|
-
end
|
78
|
-
|
79
|
-
def get_sdb(aws_id, aws_key)
|
80
|
-
Aws::SdbInterface.new(aws_id, aws_key, :logger => Logger.new(nil))
|
81
|
-
end
|
82
|
-
|
83
|
-
def sdb
|
84
|
-
@sdb ||= get_sdb(access_id, access_secret)
|
85
|
-
# @version_ok ||= check_version
|
86
|
-
@sdb
|
87
|
-
end
|
88
|
-
|
89
|
-
def s3
|
90
|
-
@s3 ||= Aws::S3.new(access_id, access_secret, :logger => Logger.new(nil))
|
91
|
-
end
|
92
|
-
|
93
|
-
def s3_bucket
|
94
|
-
@s3_bucket ||= s3.bucket(judo_config["s3_bucket"])
|
95
|
-
end
|
96
|
-
|
97
|
-
def s3_url(k)
|
98
|
-
Aws::S3Generator::Key.new(s3_bucket, k).get
|
99
|
-
end
|
100
|
-
|
101
|
-
def s3_put(k, file)
|
102
|
-
s3_bucket.put(k, file)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
data/lib/group.rb
DELETED
@@ -1,185 +0,0 @@
|
|
1
|
-
module Judo
|
2
|
-
class Group
|
3
|
-
attr_accessor :name, :dir
|
4
|
-
|
5
|
-
def self.dirs
|
6
|
-
Dir["#{Judo::Config.repo_dir}/*/config.json"].map { |d| File.dirname(d) }
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.all
|
10
|
-
@@all ||= (dirs.map { |d| new(d) })
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.find(name)
|
14
|
-
all.detect { |d| d.name == name }
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.[](name)
|
18
|
-
find(name)
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.current
|
22
|
-
all.detect { |d| Dir.pwd == d.dir or Dir.pwd =~ /^#{d.dir}\// }
|
23
|
-
end
|
24
|
-
|
25
|
-
def initialize(dir, name = File.basename(dir))
|
26
|
-
@name = name
|
27
|
-
@dir = dir
|
28
|
-
end
|
29
|
-
|
30
|
-
def create_server(server_name)
|
31
|
-
abort("Server needs a name") if server_name.nil?
|
32
|
-
# abort("Already a server named #{server_name}") if Judo::Server.find_by_name(attrs[:name]) ## FIXME
|
33
|
-
# Judo::Config.read_config(attrs[:group]) ## make sure the config is valid ## FIXME
|
34
|
-
|
35
|
-
server = Judo::Server.new server_name, self
|
36
|
-
server.task("Creating server #{server_name}") do
|
37
|
-
server.update "name" => server_name, "group" => name, "virgin" => true, "secret" => rand(2 ** 128).to_s(36)
|
38
|
-
Judo::Config.sdb.put_attributes("judo_config", "groups", name => server_name)
|
39
|
-
end
|
40
|
-
server
|
41
|
-
end
|
42
|
-
|
43
|
-
def config
|
44
|
-
@config ||= self.class.load_all(self)
|
45
|
-
end
|
46
|
-
|
47
|
-
def server_names
|
48
|
-
Judo::Config.sdb.get_attributes("judo_config", "groups")[:attributes][@name] || []
|
49
|
-
end
|
50
|
-
|
51
|
-
def servers
|
52
|
-
server_names.map { |n| Judo::Server.new(n, self) }
|
53
|
-
end
|
54
|
-
|
55
|
-
def version
|
56
|
-
@version ||= (Judo::Config.sdb.get_attributes("judo_config", "group_versions")[:attributes][@name] || ["0"]).first.to_i
|
57
|
-
end
|
58
|
-
|
59
|
-
def set_version(new_version)
|
60
|
-
@version = new_version
|
61
|
-
Judo::Config.sdb.put_attributes("judo_config", "group_versions", { name => new_version }, :replace)
|
62
|
-
end
|
63
|
-
|
64
|
-
def compile
|
65
|
-
tmpdir = "/tmp/kuzushi/#{name}"
|
66
|
-
set_version(version + 1)
|
67
|
-
puts "Compiling version #{version}"
|
68
|
-
FileUtils.rm_rf(tmpdir)
|
69
|
-
FileUtils.mkdir_p(tmpdir)
|
70
|
-
Dir.chdir(tmpdir) do |d|
|
71
|
-
attachments.each do |to,from|
|
72
|
-
FileUtils.mkdir_p(File.dirname(to))
|
73
|
-
if from =~ /^http:\/\//
|
74
|
-
puts "curl '#{from}'"
|
75
|
-
system "curl '#{from}' > #{to}"
|
76
|
-
puts "#{to} is #{File.stat(to).size} bytes"
|
77
|
-
else
|
78
|
-
FileUtils.cp(from,to)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
File.open("config.json", "w") { |f| f.write(config.to_json) }
|
82
|
-
Dir.chdir("..") do
|
83
|
-
system "tar czvf #{tar_file} #{name}"
|
84
|
-
puts "Uploading to s3..."
|
85
|
-
Judo::Config.s3_put(tar_file, File.new(tar_file))
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def tar_file
|
91
|
-
"#{name}.#{version}.tar.gz" ## FIXME needs to incorprate #{config version} "#{name}.#{version}.tar.gz"
|
92
|
-
end
|
93
|
-
|
94
|
-
def s3_url
|
95
|
-
@url = Judo::Config.s3_url(tar_file)
|
96
|
-
end
|
97
|
-
|
98
|
-
def cp_file
|
99
|
-
FileUtil.mkdir_p(tmpdir)
|
100
|
-
end
|
101
|
-
|
102
|
-
def parent
|
103
|
-
self.class.find(config["import"])
|
104
|
-
end
|
105
|
-
|
106
|
-
def extract_file(type, name, files)
|
107
|
-
path = "#{dir}/#{type}s/#{name}"
|
108
|
-
found = Dir[path]
|
109
|
-
if not found.empty?
|
110
|
-
found.each { |f| files["#{type}s/#{File.basename(f)}"] = f }
|
111
|
-
elsif parent
|
112
|
-
parent.extract_file(type, name, files)
|
113
|
-
else
|
114
|
-
raise "Cannot find file #{name} of type #{type}"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def extract(config, files)
|
119
|
-
config.each do |key,value|
|
120
|
-
[value].flatten.each do |v| ### cover "packages" : ["a","b"], "packages" : "a", "packages":[{ "file" : "foo.pkg"}]
|
121
|
-
if v.is_a? Hash
|
122
|
-
extract(v, files)
|
123
|
-
else
|
124
|
-
case key
|
125
|
-
when *[ "init", "before", "after" ]
|
126
|
-
extract_file(:script, v, files) unless v =~ /^#!/
|
127
|
-
when "package"
|
128
|
-
files["packages/#{v}_i386.deb"] = "#{config["source"]}#{v}_i386.deb"
|
129
|
-
files["packages/#{v}_amd64.deb"] = "#{config["source"]}#{v}_amd64.deb"
|
130
|
-
when "local_packages"
|
131
|
-
extract_file(:package, "#{v}_i386.deb", files)
|
132
|
-
extract_file(:package, "#{v}_amd64.deb", files)
|
133
|
-
when "template"
|
134
|
-
extract_file(:template, v, files)
|
135
|
-
when "source"
|
136
|
-
extract_file(:file, v, files) unless config["template"] or config["package"]
|
137
|
-
when "file"
|
138
|
-
extract_file(:file, File.basename(v), files) unless config["template"] or config["source"]
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
files
|
144
|
-
end
|
145
|
-
|
146
|
-
def keypair_file
|
147
|
-
extract_file(:keypair, config["key_name"] + ".pem" , {}).first
|
148
|
-
end
|
149
|
-
|
150
|
-
def attachments
|
151
|
-
extract(config, {})
|
152
|
-
end
|
153
|
-
|
154
|
-
def self.load_all(group, configs = [])
|
155
|
-
return configs.reverse.inject({}) { |sum,conf| sum.merge(conf) } unless group
|
156
|
-
raw_config = group.read_config
|
157
|
-
load_all(find(raw_config["import"]), configs << raw_config)
|
158
|
-
end
|
159
|
-
|
160
|
-
def config_file
|
161
|
-
"#{dir}/config.json"
|
162
|
-
end
|
163
|
-
|
164
|
-
def read_config
|
165
|
-
begin
|
166
|
-
JSON.parse(File.read(config_file))
|
167
|
-
rescue Errno::ENOENT
|
168
|
-
{}
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def delete_server(server)
|
173
|
-
sdb.delete_attributes("judo_config", "groups", name => server.name)
|
174
|
-
end
|
175
|
-
|
176
|
-
def to_s
|
177
|
-
name
|
178
|
-
end
|
179
|
-
|
180
|
-
def sdb
|
181
|
-
Judo::Config.sdb
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|