judo 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.7
1
+ 0.4.0
data/bin/judo CHANGED
@@ -101,9 +101,6 @@ banner
101
101
  opts.on( '-b', '--bucket BUCKET', 'Specify the AWS S3 bucket to use' ) do |bucket|
102
102
  options[:bucket] = bucket
103
103
  end
104
- opts.on( '-g', '--group GROUP', 'Specify the default group of the repo dir' ) do |group|
105
- options[:group] = group
106
- end
107
104
  opts.on( '-v', '--version VERSION', 'Update the servers config version on create/start/launch' ) do |version|
108
105
  options[:version] = version
109
106
  end
@@ -126,16 +123,16 @@ begin
126
123
  when "volumes" then do_volumes(judo)
127
124
  when "list" then do_list(judo, ARGV)
128
125
  when "groups" then do_groups(judo)
129
- when "watch" then find_servers(judo, ARGV) { |s| s.ssh_command("tail -n 1000 -f /var/log/kuzushi.log") }
130
- when "info" then find_servers(judo, ARGV) { |s| do_info(judo, s) }
131
- when "console" then find_servers(judo, ARGV) { |s| puts s.console_output }
132
- when "commit" then find_groups(judo, ARGV) { |g| g.compile }
133
- when "ssh" then find_servers(judo, ARGV) { |s| s.connect_ssh }
134
- when "start" then find_servers(judo, ARGV) { |s| s.start(options) }
135
- when "restart" then find_servers(judo, ARGV) { |s| s.restart(options) }
136
- when "stop" then find_servers(judo, ARGV) { |s| s.stop(options) }
137
- when "create" then mk_servers(judo, options, ARGV)
138
- when "launch" then mk_servers(judo, options, ARGV) { |s| s.start(options) }
126
+ when "watch" then each_server(judo, ARGV) { |s| s.ssh_command("tail -n 1000 -f /var/log/kuzushi.log") }
127
+ when "info" then each_server(judo, ARGV) { |s| do_info(judo, s) }
128
+ when "console" then each_server(judo, ARGV) { |s| puts s.console_output }
129
+ when "commit" then mk_groups(judo, ARGV) { |g| g.compile }
130
+ when "ssh" then each_server(judo, ARGV) { |s| s.connect_ssh }
131
+ when "start" then each_server(judo, ARGV) { |s| s.start(options) }
132
+ when "restart" then each_server(judo, ARGV) { |s| s.restart(options) }
133
+ when "stop" then each_server(judo, ARGV) { |s| s.stop(options) }
134
+ when "create" then mk_servers(judo, options, ARGV, false)
135
+ when "launch" then mk_servers(judo, options, ARGV, true)
139
136
  when "snapshots" then do_snapshots(judo, ARGV)
140
137
  when "config" then
141
138
  puts "Judo DB Version: #{judo.db_version}"
@@ -143,13 +140,12 @@ begin
143
140
  puts "Judo Bucket: #{judo.bucket_name}"
144
141
  when "rename" then
145
142
  raise JudoError, "usage: judo rename SERVER SERVER" unless ARGV.size == 2
146
- old,new = ARGV
147
- server = find_servers(judo, [old]).first
148
- server.rename(new)
143
+ server = judo.find_server(ARGV[0]).rename(ARGV[1])
149
144
  when "swap" then
150
- servers = find_servers(judo, ARGV)
151
- raise JudoError, "usage: judo swapip SERVER SERVER" unless servers.size == 2
152
- servers[0].swap(servers[1])
145
+ raise JudoError, "usage: judo swap SERVER SERVER" unless ARGV.size == 2
146
+ server1 = judo.find_server(ARGV[0])
147
+ server2 = judo.find_server(ARGV[1])
148
+ server1.swap(server2)
153
149
  when "erase" then
154
150
  raise JudoError, "usage: judo erase SNAPSHOT" unless ARGV.size == 1
155
151
  snapshot_name = ARGV.shift
@@ -158,10 +154,7 @@ begin
158
154
  raise JudoError, "usage: judo snapshot SERVER SNAPSHOT" unless ARGV.size == 2
159
155
  server_name = ARGV.shift
160
156
  snapshot_name = ARGV.shift
161
- servers = find_servers(judo, [server_name])
162
- raise JudoError, "You must specify a valid server to snapshot" if servers.empty?
163
- raise JudoError, "You can only snapshot one server at a time" if servers.size > 1
164
- servers[0].snapshot(snapshot_name)
157
+ judo.find_server(server_name).snapshot(snapshot_name)
165
158
  when "animate" then
166
159
  snapshot_name = ARGV.shift
167
160
  raise JudoError, "You must specify a snapshot name" unless snapshot_name
@@ -171,10 +164,9 @@ begin
171
164
  raise JudoError, "No such snapshot #{snapshot_name}" unless snapshot
172
165
  snapshot.animate(new_server).start(options)
173
166
  when "destroy" then
174
- raise JudoError, "You must specify what servers to destroy" if ARGV.empty?
175
- find_servers(judo, ARGV) do |i|
176
- i.destroy
177
- end
167
+ raise JudoError, "usage: judo destroy SERVERS" if ARGV.empty?
168
+ raise JudoError, "You cannot destroy :all" if ARGV.include?(":all")
169
+ each_server(judo, ARGV) { |i| i.destroy }
178
170
  else
179
171
  raise JudoError, "No such action #{action}"
180
172
  end
data/default/config.json CHANGED
@@ -2,7 +2,8 @@
2
2
  "ami32":"ami-2d4aa444", // public ubuntu 10.04 ami - 32 bit
3
3
  "ami64":"ami-fd4aa494", // public ubuntu 10.04 ami - 64 bit
4
4
  "user":"ubuntu", // this is for ssh acccess - defaults to ubuntu not root
5
+ "kuzushi_version": "0.0.54", // this will pin the version of kuzushi the server will boot with
5
6
  "security_group":"judo",
6
- "my_data": "world world",
7
+ "example_config": "example_mode",
7
8
  "availability_zone":"us-east-1d"
8
9
  }
@@ -0,0 +1,7 @@
1
+ ## this is an example config file for a nonexistent app
2
+ ## it will access the amount of ram and values in the config.json
3
+
4
+ memory_size = <%= @system.memory["total"].to_i / 2 %> kb ## @system comes from ohai
5
+ mode = <%= @config['example_config'] %> ## @config comes from the config.json
6
+ password = '<%= ENV['JUDO_SECRET'] %>'
7
+
data/default/setup.sh CHANGED
@@ -1,3 +1,9 @@
1
1
  #!/bin/bash
2
2
 
3
+ if [ "$JUDO_FIRST_BOOT" ] ; then
4
+ ## do some setup on the first boot only
5
+ fi
6
+
7
+ ## use kuzushi to process an erb file
8
+ kuzushi-erb example_config.erb > /etc/example_config.conf
3
9
 
data/default/userdata.erb CHANGED
@@ -1,6 +1,21 @@
1
1
  #!/bin/bash
2
2
  <%
3
3
 
4
+ ## this erb generates the userdata for your starting instance
5
+ ## in most cases you would never need to edit this as most changes can go in setup.sh
6
+
7
+ ## this script must remain under 16k to work
8
+
9
+ ## good reasons to change this would be
10
+ ## -- pass some boot options or metadata to the instance when it boots
11
+ ## -- you do not want to install or use the default version of kuzushi or judo
12
+ ## -- you wish to log the boot process differently
13
+
14
+ ## without writing a setup.sh this script will install ruby and kuzushi and
15
+ ## run kuzushi-setup which will handle waiting for the ebs disks to attach,
16
+ ## configuring them, and if needed formatting them and installing any needed
17
+ ## packages (xfs tools, mdadm)
18
+
4
19
  ## the variables available for use in the erb are as follows
5
20
 
6
21
  ## id - this is random string that uniqily identifies the server for its lifetime
@@ -21,14 +36,16 @@ export JUDO_DOMAIN='<%= domain %>'
21
36
  export JUDO_SECRET='<%= secret %>'
22
37
  export JUDO_FIRST_BOOT='<%= first_boot? %>'
23
38
 
39
+ hostname <%= name %>
40
+
24
41
  export DEBIAN_FRONTEND="noninteractive"
25
42
  export DEBIAN_PRIORITY="critical"
26
43
  apt-get update
27
44
  apt-get install -y ruby rubygems ruby-dev irb libopenssl-ruby libreadline-ruby
28
45
 
29
- cd /tmp/ ; curl --silent '<%= url %>' | tar xvz ; cd <%= group_name %>
46
+ cd /tmp/ ; curl --silent '<%= url %>' | tar xvz ; cd <%= group_name %> ; chmod 700 .
30
47
 
31
- gem install kuzushi --no-rdoc --no-ri --version
48
+ gem install kuzushi --no-rdoc --no-ri --version '<%= config['kuzushi_version'] || ">= 0" %>'
32
49
  echo 'export PATH=`ruby -r rubygems -e "puts Gem.bindir"`:$PATH' >> /etc/profile ; . /etc/profile
33
50
  export LOG=/var/log/kuzushi.log
34
51
 
data/lib/judo/base.rb CHANGED
@@ -3,9 +3,8 @@ module Judo
3
3
  attr_accessor :judo_dir, :repo, :group, :domain
4
4
 
5
5
  def initialize(options = Judo::Base.default_options)
6
- @judo_dir = options[:judo_dir]
7
- @repo = options[:repo]
8
- @group = options[:group]
6
+ @judo_dir = File.expand_path(options[:judo_dir]) if options[:judo_dir]
7
+ @repo = File.expand_path(options[:repo]) if options[:repo]
9
8
  @bucket_name = options[:bucket]
10
9
  @access_id = options[:access_id]
11
10
  @access_secret = options[:access_secret]
@@ -15,6 +14,37 @@ module Judo
15
14
  @key_create = options[:key_create]
16
15
  end
17
16
 
17
+ def find_groups(names)
18
+ return groups if names.include?(":all")
19
+ names.map do |name|
20
+ groups.detect { |g| g.displayname == name } || (raise JudoError, "No such group #{name}")
21
+ end
22
+ end
23
+
24
+ def find_server(name)
25
+ find_servers([name]).first
26
+ end
27
+
28
+ def find_servers(names)
29
+ names.map do |name|
30
+ servers.detect { |s| s.name == name || s.displayname == name } || (raise JudoError, "No such server #{name}")
31
+ end
32
+ end
33
+
34
+ def find_servers_by_name_or_groups_with_not(*names)
35
+ ok_servers = names.flatten.reject { |s| s =~ /^\^/ }
36
+ not_servers = names.flatten.select { |s| s =~ /^\^/ }.map { |s| s =~ /^\^(.*)$/ ; $1 }
37
+
38
+ find_servers_by_name_or_groups(ok_servers) - find_servers_by_name_or_groups(not_servers)
39
+ end
40
+
41
+ def find_servers_by_name_or_groups(*names)
42
+ just_servers = names.flatten.reject { |s| s =~ /^:/ }
43
+ just_groups = names.flatten.select { |s| s =~ /^:/ }
44
+
45
+ [find_groups(just_groups).map { |g| g.servers } + find_servers(just_servers)].flatten
46
+ end
47
+
18
48
  def volumes
19
49
  @volumes ||= ec2_volumes.map do |v|
20
50
  {
@@ -66,7 +96,6 @@ module Judo
66
96
  group_config = Dir["#{repo_dir}/*/config.json"].detect { |d| File.dirname(d) == pwd }
67
97
  {
68
98
  :judo_dir => dir,
69
- :group => group_config ? File.basename(File.dirname(group_config)) : nil,
70
99
  :repo => repo_dir,
71
100
  :domain => (config["domain"] || ENV['JUDO_DOMAIN']),
72
101
  :bucket => (config["s3_bucket"] || ENV['JUDO_BUCKET']),
@@ -148,7 +177,7 @@ module Judo
148
177
 
149
178
  def mk_server_name(group)
150
179
  index = servers.map { |s| (s.name =~ /^#{s.group.name}.(\d*)$/); $1.to_i }.sort.last.to_i + 1
151
- "#{group}.#{index}"
180
+ "#{group}#{index}"
152
181
  end
153
182
 
154
183
  def create_server(name, group, options)
@@ -183,7 +212,7 @@ module Judo
183
212
  end
184
213
 
185
214
  def groups
186
- @groups ||= group_versions.map { |name,ver| Judo::Group.new(self, name, ver.first.to_i ) }
215
+ @groups ||= group_versions.map { |name,ver| Judo::Group.new(self, name) }
187
216
  end
188
217
 
189
218
  def reload_ec2_instances
@@ -393,9 +422,7 @@ module Judo
393
422
  return
394
423
  end
395
424
  task("Setting up default group") do
396
- Dir.chdir(repo) do
397
- File.open("default/config.json","w") { |f| f.write default_config }
398
- end
425
+ FileUtils.cp_r(default_group_dir, repo)
399
426
  get_group("default").compile
400
427
  end
401
428
  end
@@ -1,74 +1,53 @@
1
1
  module JudoCommandLineHelpers
2
- def judo_yield(arg, blk)
3
- begin
4
- blk.call(arg)
5
- rescue JudoInvalid => e
6
- puts "#{arg} - #{e.message}"
7
- end
8
- end
9
2
 
10
- def split(string)
11
- if string =~ /([^:]*):(.*)/
12
- [ $1, $2 ]
13
- else
14
- [ string, nil]
3
+ def each_server(judo, args, &blk)
4
+ raise JudoError, "No servers specified - use :all for all servers" if args.empty?
5
+ servers = judo.find_servers_by_name_or_groups_with_not(args)
6
+ servers.each do |server|
7
+ begin
8
+ blk.call(server)
9
+ rescue JudoInvalid => e
10
+ puts "#{server} - #{e.message}"
11
+ end
15
12
  end
16
13
  end
17
14
 
18
- def find_groups(judo, args, &blk)
19
- raise JudoError, "No groups specified" if args.empty? and judo.group.nil?
20
-
21
- args << ":#{judo.group}" if args.empty? ## use default group if none specified
22
-
23
- groups = args.map do |arg|
24
- name,group = split(arg)
25
- raise JudoError, "specify a group with ':GROUP'" unless name == "" and group
26
- judo.get_group(group)
27
- end
28
-
29
- groups.each { |group| judo_yield(group, blk) if blk }
30
- end
31
-
32
- ## I dont like the way this is working anymore - needs refactor
33
- def mk_servers(judo, options, args, &blk)
34
- servers = args.map do |arg|
35
- name,group = split(arg)
36
- group ||= judo.group
37
- raise JudoError, "Cannot must specify a server, not a group, on create and launch" unless name
38
- if name =~ /^\+(\d+)/
39
- count = $1.to_i
15
+ def mk_server_names(judo, args, &blk)
16
+ args.each do |arg|
17
+ name,group = arg.split(":")
18
+ raise JudoError, "You must specify a group on create and launch" unless group
19
+ names = if name =~ /^[12345]$/
20
+ (1..(name.to_i)).each do
21
+ blk.call(judo.mk_server_name(group), group)
22
+ end
23
+ elsif name == ""
24
+ blk.call(judo.mk_server_name(group), group)
25
+ elsif name =~ /^\d+$/
40
26
  raise JudoError, "You can batch-create between 1 and 5 servers" if count < 1 or count > 5
41
- (1..count).map { judo.create_server( judo.mk_server_name(group), group, options) }
42
27
  else
43
- judo.create_server(name, group, options)
28
+ blk.call(name, group)
44
29
  end
45
30
  end
46
- servers.flatten.each { |s| judo_yield(s, blk) if blk }
47
31
  end
48
32
 
49
- def find_servers(judo, args, use_default = true, &blk)
50
- servers = judo.servers if args.empty?
51
- servers ||= args.map { |a| find_server(judo, a, use_default) }.flatten
52
-
53
- raise JudoError, "No servers" if servers.empty?
54
-
55
- servers.each { |s| judo_yield(s,blk) if blk }
56
- servers
33
+ def mk_groups(judo, args, &blk)
34
+ args.each do |name|
35
+ if name =~ /:(.+)$/
36
+ blk.call(Judo::Group.new(judo, $1))
37
+ else
38
+ raise JudoError, "Invalid group name '#{name}'"
39
+ end
40
+ end
57
41
  end
58
42
 
59
- def find_server(judo, arg, use_default = false)
60
- ## this assumes names are unique no matter the group
61
- name,group = split(arg)
62
- if name != ""
63
- server = judo.servers.detect { |s| s.name == name }
64
- raise JudoError, "No such server #{name}" unless server
65
- raise JudoError, "Server #{name} not in group #{group}" if group and server.group.name != group
66
- server
67
- else
68
- group ||= judo.group if use_default
69
- g = judo.groups.detect { |g| g.name == group }
70
- raise JudoError, "No such group #{group}" unless g
71
- g.servers
43
+ def mk_servers(judo, options, args, start)
44
+ mk_server_names(judo, args) do |name, group|
45
+ begin
46
+ server = judo.create_server(name, group, options)
47
+ server.start(options) if start
48
+ rescue JudoInvalid => e
49
+ puts "#{server} - #{e.message}"
50
+ end
72
51
  end
73
52
  end
74
53
 
@@ -108,20 +87,18 @@ module JudoCommandLineHelpers
108
87
  end
109
88
 
110
89
  def do_snapshots(judo, args)
111
- servers = find_servers(judo, args)
112
90
  printf " SNAPSHOTS\n"
113
91
  printf "%s\n", ("-" * 80)
114
92
  judo.snapshots.each do |snapshot|
115
- next if args and not servers.detect { |s| s == snapshot.server }
116
93
  printf "%-15s %-25s %-15s %-10s %s\n", snapshot.name, snapshot.server_name, snapshot.group_name, snapshot.version_desc, "ebs:#{snapshot.ec2_ids.size}"
117
94
  end
118
95
  end
119
96
 
120
97
  def do_list(judo, args)
121
- servers = find_servers(judo, args)
122
98
  printf " SERVERS\n"
123
99
  printf "%s\n", ("-" * 80)
124
- servers.sort.each do |s|
100
+ args << ":all" if args.empty?
101
+ each_server(judo,args) do |s|
125
102
  printf "%-32s %-12s %-7s %-11s %-11s %-10s %-3s %s\n", s.name, s.group.name, s.version_desc, s.get("instance_id"), s.size_desc, s.ec2_state, "ebs:#{s.volumes.keys.size}", s.has_ip? ? "ip" : ""
126
103
  end
127
104
  end
data/lib/judo/group.rb CHANGED
@@ -2,10 +2,13 @@ module Judo
2
2
  class Group
3
3
  attr_accessor :name, :version
4
4
 
5
- def initialize(base, name, version)
5
+ def initialize(base, name)
6
6
  @base = base
7
7
  @name = name
8
- @version = version
8
+ end
9
+
10
+ def version
11
+ @version ||= (@base.group_versions[@name] || [0]).first.to_i
9
12
  end
10
13
 
11
14
  def userdata(version)
@@ -21,7 +24,7 @@ module Judo
21
24
  end
22
25
 
23
26
  def servers
24
- @base.servers.select { |s| server_ids.include?(s.name) }
27
+ @base.servers.select { |s| server_ids.include?(s.id) }
25
28
  end
26
29
 
27
30
  def load_userdata(version)
@@ -41,8 +44,9 @@ module Judo
41
44
  end
42
45
 
43
46
  def compile
47
+ raise JudoError, "Group name :all is reserved" if name == "all"
44
48
  @base.task("Compiling #{self} version #{version + 1}") do
45
- @version = @version + 1
49
+ @version = version + 1
46
50
  raise JudoError, "can not find group folder #{dir}" unless File.exists?(dir)
47
51
  conf = JSON.parse(read_file('config.json'))
48
52
  raise JudoError, "config option 'import' no longer supported" if conf["import"]
@@ -107,10 +111,14 @@ module Judo
107
111
  sdb.delete_attributes(@base.base_domain, "groups", name => server.id)
108
112
  end
109
113
 
110
- def to_s
114
+ def displayname
111
115
  ":#{name}"
112
116
  end
113
117
 
118
+ def to_s
119
+ displayname
120
+ end
121
+
114
122
  def sdb
115
123
  @base.sdb
116
124
  end
data/lib/judo/server.rb CHANGED
@@ -10,7 +10,7 @@ module Judo
10
10
  end
11
11
 
12
12
  def create(name, options)
13
- raise JudoError, "no group specified" unless group_name
13
+ raise JudoError, "group '#{group_name}' does not exists" unless group
14
14
 
15
15
  options[:virgin] = true if options[:virgin].nil?
16
16
 
@@ -212,10 +212,14 @@ module Judo
212
212
  group.config(version)
213
213
  end
214
214
 
215
- def to_s
215
+ def displayname
216
216
  "#{name}:#{group_name}"
217
217
  end
218
218
 
219
+ def to_s
220
+ displayname
221
+ end
222
+
219
223
  def allocate_disk(snapshots)
220
224
  if snapshots
221
225
  clone_snapshots(snapshots)
data/lib/judo/snapshot.rb CHANGED
@@ -89,6 +89,7 @@ module Judo
89
89
  end
90
90
 
91
91
  def delete
92
+ ### TODO - wait for snapshotting to finish
92
93
  @base.sdb.delete_attributes(@base.snapshot_domain, name)
93
94
  server.remove("snapshots", name) if server
94
95
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
8
- - 7
9
- version: 0.3.7
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Orion Henry
@@ -59,6 +59,7 @@ files:
59
59
  - VERSION
60
60
  - bin/judo
61
61
  - default/config.json
62
+ - default/example_config.erb
62
63
  - default/setup.sh
63
64
  - default/userdata.erb
64
65
  - lib/judo.rb