judo 0.3.7 → 0.4.0

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/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