wakame 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +18 -0
- data/README.rdoc +2 -4
- data/Rakefile +4 -1
- data/VERSION +1 -1
- data/app_generators/wakame/templates/config/cluster.rb +36 -0
- data/app_generators/wakame/wakame_generator.rb +1 -0
- data/lib/wakame/action.rb +19 -34
- data/lib/wakame/actions/launch_cluster.rb +6 -3
- data/lib/wakame/actions/launch_vm.rb +57 -0
- data/lib/wakame/actions/migrate_service.rb +6 -25
- data/lib/wakame/actions/propagate_instances.rb +16 -41
- data/lib/wakame/actions/reload_service.rb +2 -2
- data/lib/wakame/actions/shutdown_cluster.rb +4 -0
- data/lib/wakame/actions/start_service.rb +30 -9
- data/lib/wakame/actions/stop_service.rb +1 -4
- data/lib/wakame/actions/util.rb +0 -24
- data/lib/wakame/actor/mysql.rb +106 -0
- data/lib/wakame/actor/service_monitor.rb +10 -0
- data/lib/wakame/actor/system.rb +19 -9
- data/lib/wakame/actor.rb +1 -1
- data/lib/wakame/agent.rb +23 -17
- data/lib/wakame/command/action_status.rb +7 -38
- data/lib/wakame/command/agent_status.rb +18 -0
- data/lib/wakame/command/launch_cluster.rb +0 -4
- data/lib/wakame/command/launch_vm.rb +11 -0
- data/lib/wakame/command/migrate_service.rb +12 -9
- data/lib/wakame/command/propagate_service.rb +15 -7
- data/lib/wakame/command/reload_service.rb +21 -0
- data/lib/wakame/command/shutdown_cluster.rb +0 -5
- data/lib/wakame/command/shutdown_vm.rb +20 -0
- data/lib/wakame/command/status.rb +6 -66
- data/lib/wakame/command/stop_service.rb +31 -0
- data/lib/wakame/command.rb +3 -0
- data/lib/wakame/command_queue.rb +76 -5
- data/lib/wakame/configuration.rb +6 -1
- data/lib/wakame/event.rb +6 -5
- data/lib/wakame/event_dispatcher.rb +5 -3
- data/lib/wakame/initializer.rb +1 -1
- data/lib/wakame/master.rb +14 -10
- data/lib/wakame/monitor/agent.rb +1 -6
- data/lib/wakame/monitor/service.rb +13 -1
- data/lib/wakame/packets.rb +51 -13
- data/lib/wakame/rule_engine.rb +7 -18
- data/lib/wakame/runner/administrator_command.rb +517 -46
- data/lib/wakame/service.rb +104 -173
- data/lib/wakame/trigger.rb +1 -10
- data/lib/wakame/triggers/process_command.rb +9 -2
- data/lib/wakame/util.rb +21 -21
- data/lib/wakame/vm_manipulator.rb +1 -0
- data/tests/test_service.rb +30 -6
- data/wakame_generators/resource/templates/ec2_elb/ec2_elb.rb +80 -0
- data/wakame_generators/resource/templates/mysql_master/conf/my.cnf +3 -1
- data/wakame_generators/resource/templates/mysql_master/init.d/mysql +3 -3
- data/wakame_generators/resource/templates/mysql_master/mysql_master.rb +11 -12
- data/{app_generators/wakame/templates/cluster/resources/mysql_master → wakame_generators/resource/templates/mysql_slave}/conf/my.cnf +19 -9
- data/{app_generators/wakame/templates/cluster/resources/mysql_master/init.d/mysql → wakame_generators/resource/templates/mysql_slave/init.d/mysql-slave} +4 -4
- data/wakame_generators/resource/templates/mysql_slave/mysql_slave.rb +123 -0
- data/wakame_generators/resource/templates/nginx/conf/nginx.conf +166 -0
- data/wakame_generators/resource/templates/nginx/init.d/nginx +70 -0
- data/{app_generators/wakame/templates/cluster/resources/apache_lb/apache_lb.rb → wakame_generators/resource/templates/nginx/nginx.rb} +28 -17
- metadata +46 -27
- data/app_generators/wakame/templates/cluster/resources/apache_app/apache_app.rb +0 -54
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/apache2.conf +0 -46
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/envvars-app +0 -7
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/sites-app.conf +0 -23
- data/app_generators/wakame/templates/cluster/resources/apache_app/conf/system-app.conf +0 -67
- data/app_generators/wakame/templates/cluster/resources/apache_app/init.d/apache2-app +0 -192
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/apache2.conf +0 -46
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/envvars-lb +0 -6
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/sites-lb.conf +0 -54
- data/app_generators/wakame/templates/cluster/resources/apache_lb/conf/system-lb.conf +0 -75
- data/app_generators/wakame/templates/cluster/resources/apache_lb/init.d/apache2-lb +0 -192
- data/app_generators/wakame/templates/cluster/resources/apache_www/apache_www.rb +0 -50
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/apache2.conf +0 -47
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/envvars-www +0 -7
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/sites-www.conf +0 -23
- data/app_generators/wakame/templates/cluster/resources/apache_www/conf/system-www.conf +0 -63
- data/app_generators/wakame/templates/cluster/resources/apache_www/init.d/apache2-www +0 -192
- data/app_generators/wakame/templates/cluster/resources/ec2_elastic_ip/ec2_elastic_ip.rb +0 -39
- data/app_generators/wakame/templates/cluster/resources/mysql_master/mysql_master.rb +0 -174
- data/tests/conf/a +0 -1
- data/tests/conf/b +0 -1
- data/tests/conf/c +0 -1
data/lib/wakame/service.rb
CHANGED
@@ -97,7 +97,7 @@ module Wakame
|
|
97
97
|
include ThreadImmutable
|
98
98
|
|
99
99
|
attr_reader :dg, :instance_id, :status_changed_at, :rule_engine, :master
|
100
|
-
attr_reader :status
|
100
|
+
attr_reader :status, :lock_queue
|
101
101
|
|
102
102
|
STATUS_OFFLINE = 0
|
103
103
|
STATUS_ONLINE = 1
|
@@ -108,6 +108,7 @@ module Wakame
|
|
108
108
|
@master = master
|
109
109
|
@instance_id =Wakame.gen_id
|
110
110
|
@rule_engine ||= RuleEngine.new(self)
|
111
|
+
@lock_queue = LockQueue.new(self)
|
111
112
|
prepare
|
112
113
|
|
113
114
|
instance_eval(&blk) if blk
|
@@ -289,7 +290,7 @@ module Wakame
|
|
289
290
|
r[:instances][k]=i.dump_status
|
290
291
|
}
|
291
292
|
properties.each { |k, i|
|
292
|
-
r[:properties][k] = i.
|
293
|
+
r[:properties][k] = i.dump_attrs
|
293
294
|
r[:properties][k][:instances] = each_instance(i.class).collect{|k, v| k }
|
294
295
|
}
|
295
296
|
|
@@ -351,8 +352,109 @@ module Wakame
|
|
351
352
|
|
352
353
|
end
|
353
354
|
thread_immutable_methods :update_cluster_status
|
355
|
+
|
356
|
+
end
|
354
357
|
|
358
|
+
class LockQueue
|
359
|
+
def initialize(cluster)
|
360
|
+
@service_cluster = cluster
|
361
|
+
@locks = {}
|
362
|
+
@id2res = {}
|
363
|
+
|
364
|
+
@queue_by_thread = {}
|
365
|
+
@qbt_m = ::Mutex.new
|
366
|
+
end
|
355
367
|
|
368
|
+
def set(resource, id)
|
369
|
+
# Ths Job ID already holds/reserves the lock regarding the resource.
|
370
|
+
return if @id2res.has_key?(id) && @id2res[id].has_key?(resource.to_s)
|
371
|
+
|
372
|
+
EM.barrier {
|
373
|
+
@locks[resource.to_s] ||= []
|
374
|
+
@id2res[id] ||= {}
|
375
|
+
|
376
|
+
@id2res[id][resource.to_s]=1
|
377
|
+
@locks[resource.to_s] << id
|
378
|
+
}
|
379
|
+
Wakame.log.debug("#{self.class}: set(#{resource.to_s}, #{id})" + "\n#{self.inspect}")
|
380
|
+
end
|
381
|
+
|
382
|
+
def reset()
|
383
|
+
@locks.keys { |k|
|
384
|
+
@locks[k].clear
|
385
|
+
}
|
386
|
+
@id2res.clear
|
387
|
+
end
|
388
|
+
|
389
|
+
def test(id)
|
390
|
+
reslist = @id2res[id]
|
391
|
+
return :pass if reslist.nil? || reslist.empty?
|
392
|
+
|
393
|
+
#
|
394
|
+
if reslist.keys.all? { |r| id == @locks[r.to_s][0] }
|
395
|
+
return :runnable
|
396
|
+
else
|
397
|
+
return :wait
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
def wait(id, tout=60*30)
|
402
|
+
@qbt_m.synchronize { @queue_by_thread[Thread.current] = ::Queue.new }
|
403
|
+
|
404
|
+
timeout(tout) {
|
405
|
+
while test(id) == :wait
|
406
|
+
Wakame.log.debug("#{self.class}: Job #{id} waits for locked resouces: #{@id2res[id].keys.join(', ')}")
|
407
|
+
break if id == @queue_by_thread[Thread.current].deq
|
408
|
+
end
|
409
|
+
}
|
410
|
+
ensure
|
411
|
+
@qbt_m.synchronize { @queue_by_thread.delete(Thread.current) }
|
412
|
+
end
|
413
|
+
|
414
|
+
def quit(id)
|
415
|
+
EM.barrier {
|
416
|
+
case test(id)
|
417
|
+
when :runnable, :wait
|
418
|
+
@id2res[id].keys.each { |r| @locks[r.to_s].delete_if{ |i| i == id } }
|
419
|
+
@qbt_m.synchronize {
|
420
|
+
@queue_by_thread.each {|t, q| q.enq(id) }
|
421
|
+
}
|
422
|
+
end
|
423
|
+
|
424
|
+
@id2res.delete(id)
|
425
|
+
}
|
426
|
+
Wakame.log.debug("#{self.class}: quit(#{id})" + "\n#{self.inspect}")
|
427
|
+
end
|
428
|
+
|
429
|
+
def clear_resource(resource)
|
430
|
+
end
|
431
|
+
|
432
|
+
def inspect
|
433
|
+
output = @locks.collect { |k, lst|
|
434
|
+
[k, lst].flatten
|
435
|
+
}
|
436
|
+
return "" if output.empty?
|
437
|
+
|
438
|
+
# Table display
|
439
|
+
maxcolws = (0..(output.size)).zip(*output).collect { |i| i.shift; i.map!{|i| (i.nil? ? "" : i).length }.max }
|
440
|
+
maxcol = maxcolws.size
|
441
|
+
maxcolws.reverse.each { |i|
|
442
|
+
break if i > 0
|
443
|
+
maxcol -= 1
|
444
|
+
}
|
445
|
+
|
446
|
+
textrows = output.collect { |x|
|
447
|
+
buf=""
|
448
|
+
maxcol.times { |n|
|
449
|
+
buf << "|" + (x[n] || "").ljust(maxcolws[n])
|
450
|
+
}
|
451
|
+
buf << "|"
|
452
|
+
}
|
453
|
+
|
454
|
+
"+" + (["-"] * (textrows[0].length - 2)).join('') + "+\n" + \
|
455
|
+
textrows.join("\n") + \
|
456
|
+
"\n+" + (["-"] * (textrows[0].length - 2)).join('')+ "+"
|
457
|
+
end
|
356
458
|
end
|
357
459
|
|
358
460
|
|
@@ -736,179 +838,8 @@ end
|
|
736
838
|
|
737
839
|
module Wakame
|
738
840
|
module Service
|
739
|
-
|
740
|
-
|
741
841
|
module ApacheBasicProps
|
742
842
|
attr_accessor :listen_port, :listen_port_https, :server_root
|
743
|
-
|
744
|
-
end
|
745
|
-
|
746
|
-
class MySQL_Slave < Property
|
747
|
-
attr_reader :basedir, :mysqld_datadir, :mysqld_port, :mysqld_server_id, :mysqld_log_bin, :ebs_volume, :ebs_device
|
748
|
-
|
749
|
-
def initialize
|
750
|
-
super()
|
751
|
-
@template = ConfigurationTemplate::MySQLSlaveTemplate.new()
|
752
|
-
@basedir = '/home/wakame/mysql'
|
753
|
-
|
754
|
-
@mysqld_server_id = 2 # dynamic
|
755
|
-
@mysqld_port = 3307
|
756
|
-
@mysqld_datadir = File.expand_path('data-slave', @basedir)
|
757
|
-
|
758
|
-
@ebs_volume = 'vol-38bc5f51' # master volume_id
|
759
|
-
@ebs_device = '/dev/sdn' # slave mount point
|
760
|
-
@ebs_mount_option = 'noatime'
|
761
|
-
|
762
|
-
@mysqld_master_host = '10.249.2.115'
|
763
|
-
@mysqld_master_user = 'wakame-repl'
|
764
|
-
@mysqld_master_pass = 'wakame-slave'
|
765
|
-
@mysqld_master_port = 3306
|
766
|
-
@mysqld_master_datadir = File.expand_path('data', @basedir)
|
767
|
-
|
768
|
-
@duplicable = false
|
769
|
-
end
|
770
|
-
|
771
|
-
def before_start(svc, action)
|
772
|
-
vm_manipulator = VmManipulator.create
|
773
|
-
|
774
|
-
Wakame.log.debug("mkdir #{@mysqld_datadir}")
|
775
|
-
system("[ -d #{@mysqld_datadir} ] || mkdir -p #{@mysqld_datadir}")
|
776
|
-
Wakame.log.debug("[ -b #{@ebs_device} ]")
|
777
|
-
system("[ -b #{@ebs_device} ]")
|
778
|
-
if $? == 0
|
779
|
-
Wakame.log.debug("The EBS volume(slave) device is not ready to attach: #{@ebs_device}")
|
780
|
-
return
|
781
|
-
end
|
782
|
-
|
783
|
-
volume_map = vm_manipulator.describe_volume(@ebs_volume)
|
784
|
-
Wakame.log.debug("describe_volume(#{@ebs_volume}): #{volume_map.inspect}")
|
785
|
-
if volume_map['status'] == 'in-use'
|
786
|
-
# Nothin to be done
|
787
|
-
else
|
788
|
-
Wakame.log.debug("The EBS volume(slave) is not ready to attach: #{@ebs_volume}")
|
789
|
-
return
|
790
|
-
end
|
791
|
-
|
792
|
-
system("echo show master status | /usr/bin/mysql -h#{@mysqld_master_host} -P#{@mysqld_master_port} -u#{@mysqld_master_user} -p#{@mysqld_master_pass}")
|
793
|
-
if $? != 0
|
794
|
-
raise "Can't connect mysql master: #{@mysqld_master_host}:#{@mysqld_master_port}"
|
795
|
-
end
|
796
|
-
|
797
|
-
system("echo 'FLUSH TABLES WITH READ LOCK;' | /usr/bin/mysql -h#{@mysqld_master_host} -P#{@mysqld_master_port} -u#{@mysqld_master_user} -p#{@mysqld_master_pass} -s")
|
798
|
-
master_status = `echo show master status | /usr/bin/mysql -h#{@mysqld_master_host} -P#{@mysqld_master_port} -u#{@mysqld_master_user} -p#{@mysqld_master_pass} -s`.to_s.split(/\t/)[0..1]
|
799
|
-
# p master_status
|
800
|
-
|
801
|
-
# mysql/data/master.info
|
802
|
-
master_infos = []
|
803
|
-
master_infos << 14
|
804
|
-
master_infos << master_status[0]
|
805
|
-
master_infos << master_status[1]
|
806
|
-
master_infos << @mysqld_master_host
|
807
|
-
master_infos << @mysqld_master_user
|
808
|
-
master_infos << @mysqld_master_pass
|
809
|
-
master_infos << @mysqld_master_port
|
810
|
-
master_infos << 60
|
811
|
-
master_infos << 0
|
812
|
-
master_infos << ""
|
813
|
-
master_infos << ""
|
814
|
-
master_infos << ""
|
815
|
-
master_infos << ""
|
816
|
-
master_infos << ""
|
817
|
-
master_infos << ""
|
818
|
-
|
819
|
-
tmp_output_basedir = File.expand_path(Wakame.gen_id, "/tmp")
|
820
|
-
FileUtils.mkdir_p tmp_output_basedir
|
821
|
-
master_info = File.expand_path('master.info', tmp_output_basedir)
|
822
|
-
file = File.new(master_info, "w")
|
823
|
-
file.puts(master_infos.join("\n"))
|
824
|
-
file.chmod(0664)
|
825
|
-
file.close
|
826
|
-
|
827
|
-
3.times do |i|
|
828
|
-
system("/bin/sync")
|
829
|
-
sleep 1.0
|
830
|
-
end
|
831
|
-
|
832
|
-
Wakame.log.debug("scp -i #{Wakame.config.ssh_private_key} -o \"UserKnownHostsFile #{Wakame.config.ssh_known_hosts}\" #{master_info} root@#{@mysqld_master_host}:#{@mysqld_master_datadir}/" )
|
833
|
-
system("scp -i #{Wakame.config.ssh_private_key} -o \"UserKnownHostsFile #{Wakame.config.ssh_known_hosts}\" #{master_info} root@#{@mysqld_master_host}:#{@mysqld_master_datadir}/" )
|
834
|
-
Wakame.log.debug("ssh -i #{Wakame.config.ssh_private_key} -o \"UserKnownHostsFile #{Wakame.config.ssh_known_hosts}\" root@#{@mysqld_master_host} chown mysql:mysql #{@mysqld_master_datadir}/master.info" )
|
835
|
-
system("ssh -i #{Wakame.config.ssh_private_key} -o \"UserKnownHostsFile #{Wakame.config.ssh_known_hosts}\" root@#{@mysqld_master_host} chown mysql:mysql #{@mysqld_master_datadir}/master.info" )
|
836
|
-
|
837
|
-
3.times do |i|
|
838
|
-
system("/bin/sync")
|
839
|
-
sleep 1.0
|
840
|
-
end
|
841
|
-
|
842
|
-
FileUtils.rm_rf tmp_output_basedir
|
843
|
-
|
844
|
-
# 2. snapshot
|
845
|
-
Wakame.log.debug("create_snapshot (#{@ebs_volume})")
|
846
|
-
snapshot_map = vm_manipulator.create_snapshot(@ebs_volume)
|
847
|
-
16.times do |i|
|
848
|
-
Wakame.log.debug("describe_snapshot(#{snapshot_map.snapshotId}) ... #{i}")
|
849
|
-
snapshot_map = vm_manipulator.describe_snapshot(snapshot_map["snapshotId"])
|
850
|
-
if snapshot_map["status"] == "completed"
|
851
|
-
break
|
852
|
-
end
|
853
|
-
sleep 1.0
|
854
|
-
end
|
855
|
-
if snapshot_map["status"] != "completed"
|
856
|
-
raise "#{snapshot_map.snapshotId} status is #{snapshot_map.status}"
|
857
|
-
end
|
858
|
-
|
859
|
-
# 3. unlock mysql-master
|
860
|
-
system("echo 'UNLOCK TABLES;' | /usr/bin/mysql -h#{@mysqld_master_host} -P#{@mysqld_master_port} -u#{@mysqld_master_user} -p#{@mysqld_master_pass}")
|
861
|
-
|
862
|
-
# create volume /dev/xxxx
|
863
|
-
Wakame.log.debug("create_volume_from_snapshot(#{volume_map.availabilityZone}, #{snapshot_map.snapshotId})")
|
864
|
-
created_volume_from_snapshot_map = vm_manipulator.create_volume_from_snapshot(volume_map["availabilityZone"], snapshot_map["snapshotId"])
|
865
|
-
volume_from_snapshot_map = created_volume_from_snapshot_map
|
866
|
-
16.times do |i|
|
867
|
-
Wakame.log.debug("describe_snapshot(#{snapshot_map.snapshotId}) ... #{i}")
|
868
|
-
volume_from_snapshot_map = vm_manipulator.describe_snapshot(snapshot_map["snapshotId"])
|
869
|
-
if volume_from_snapshot_map["status"] == "completed"
|
870
|
-
break
|
871
|
-
end
|
872
|
-
sleep 1.0
|
873
|
-
end
|
874
|
-
if volume_from_snapshot_map["status"] != "completed"
|
875
|
-
raise "#{volume_from_snapshot_map.snapshotId} status is #{volume_from_snapshot_map.status}"
|
876
|
-
end
|
877
|
-
|
878
|
-
# attach volume
|
879
|
-
attach_volume_map = vm_manipulator.attach_volume(svc.agent.agent_id, created_volume_from_snapshot_map["volumeId"], @ebs_device)
|
880
|
-
16.times do |i|
|
881
|
-
Wakame.log.debug("describe_volume(#{attach_volume_map.volumeId}) ... #{i}")
|
882
|
-
attach_volume_map = vm_manipulator.describe_volume(created_volume_from_snapshot_map["volumeId"])
|
883
|
-
if attach_volume_map["status"] == "in-use"
|
884
|
-
break
|
885
|
-
end
|
886
|
-
sleep 1.0
|
887
|
-
end
|
888
|
-
if attach_volume_map["status"] != "in-use"
|
889
|
-
raise "#{attach_volume_map.volumeId} status is #{attach_volume_map.status}"
|
890
|
-
end
|
891
|
-
end
|
892
|
-
|
893
|
-
def start
|
894
|
-
mount_point_dev=`df "#{@mysqld_datadir}" | awk 'NR==2 {print $1}'`
|
895
|
-
if mount_point_dev != @ebs_device
|
896
|
-
Wakame.log.debug("Mounting EBS volume: #{@ebs_device} as #{@mysqld_datadir} (with option: #{@ebs_mount_option})")
|
897
|
-
system("/bin/mount -o #{@ebs_mount_option} #{@ebs_device} #{@mysqld_datadir}")
|
898
|
-
end
|
899
|
-
system(Wakame.config.root + "/config/init.d/mysql-slave start")
|
900
|
-
end
|
901
|
-
|
902
|
-
def check
|
903
|
-
system("/usr/bin/mysqladmin --defaults-file=/home/wakame/config/mysql-slave/my-slave.cnf ping > /dev/null")
|
904
|
-
return false if $? != 0
|
905
|
-
true
|
906
|
-
end
|
907
|
-
|
908
|
-
def stop
|
909
|
-
system(Wakame.config.root + "/config/init.d/mysql-slave stop")
|
910
|
-
end
|
911
843
|
end
|
912
|
-
|
913
844
|
end
|
914
845
|
end
|
data/lib/wakame/trigger.rb
CHANGED
@@ -27,17 +27,8 @@ module Wakame
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def trigger_action(action)
|
30
|
-
found = rule_engine.active_jobs.find { |id, job|
|
31
|
-
job[:src_rule].class == self.class
|
32
|
-
}
|
33
|
-
|
34
|
-
if found
|
35
|
-
Wakame.log.warn("#{self.class}: Exisiting Job \"#{found[:job_id]}\" was kicked from this rule and it's still running. Skipping...")
|
36
|
-
raise CancelActionError
|
37
|
-
end
|
38
|
-
|
39
30
|
rule_engine.create_job_context(self, action)
|
40
|
-
action.
|
31
|
+
action.bind_trigger(self)
|
41
32
|
|
42
33
|
rule_engine.run_action(action)
|
43
34
|
action.job_id
|
@@ -2,6 +2,13 @@
|
|
2
2
|
module Wakame
|
3
3
|
module Triggers
|
4
4
|
class ProcessCommand < Trigger
|
5
|
+
def_attribute :status
|
6
|
+
def_attribute :job_id
|
7
|
+
def_attribute :completion_status
|
8
|
+
def_attribute :parent_action
|
9
|
+
def_attribute :acquire_lock, false
|
10
|
+
|
11
|
+
attr_reader :trigger
|
5
12
|
def register_hooks
|
6
13
|
@@command_thread ||= Thread.new {
|
7
14
|
while cmd = self.command_queue.deq_cmd
|
@@ -9,8 +16,8 @@ module Wakame
|
|
9
16
|
begin
|
10
17
|
EM.barrier {
|
11
18
|
Wakame.log.debug("#{self.class}: Being processed the command: #{cmd.class}")
|
12
|
-
cmd.run(self)
|
13
|
-
res
|
19
|
+
res = cmd.run(self)
|
20
|
+
res
|
14
21
|
}
|
15
22
|
rescue => e
|
16
23
|
Wakame.log.error(e)
|
data/lib/wakame/util.rb
CHANGED
@@ -206,29 +206,29 @@ module AttributeHelper
|
|
206
206
|
@attr_attributes ||= {}
|
207
207
|
end
|
208
208
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
209
|
+
# def attr(name, assignable=false)
|
210
|
+
# attr_attributes[name.to_sym]={}
|
211
|
+
# attr_without_trap(name, assignable)
|
212
|
+
# end
|
213
213
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
214
|
+
# # Override Object.attr_accessor to
|
215
|
+
# def attr_accessor(*args)
|
216
|
+
# args.each { |name|
|
217
|
+
# attr(name, true)
|
218
|
+
# }
|
219
|
+
# end
|
220
220
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
221
|
+
# def attr_reader(*args)
|
222
|
+
# args.each { |name|
|
223
|
+
# attr(name, false)
|
224
|
+
# }
|
225
|
+
# end
|
226
226
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
227
|
+
# def attr_writer(*args)
|
228
|
+
# args.each { |name|
|
229
|
+
# attr(name, true)
|
230
|
+
# }
|
231
|
+
# end
|
232
232
|
|
233
233
|
def def_attribute(name, *args)
|
234
234
|
attr = {}
|
@@ -276,7 +276,7 @@ module AttributeHelper
|
|
276
276
|
private
|
277
277
|
def self.included(klass)
|
278
278
|
klass.class.class_eval {
|
279
|
-
alias :attr_without_trap :attr unless self.respond_to?(:attr_without_trap, true)
|
279
|
+
#alias :attr_without_trap :attr unless self.respond_to?(:attr_without_trap, true)
|
280
280
|
}
|
281
281
|
klass.extend ClassMethods
|
282
282
|
end
|
data/tests/test_service.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
|
2
2
|
|
3
|
-
$:.unshift
|
4
|
-
|
3
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$:.unshift(File.dirname(__FILE__))
|
5
5
|
|
6
|
-
require '
|
7
|
-
require 'wakame'
|
8
|
-
require 'wakame/service.rb'
|
6
|
+
require 'setup_master.rb'
|
9
7
|
|
10
|
-
|
8
|
+
require 'wakame/service.rb'
|
11
9
|
|
12
10
|
class TestService < Test::Unit::TestCase
|
13
11
|
include Wakame::Service
|
@@ -57,4 +55,30 @@ class TestService < Test::Unit::TestCase
|
|
57
55
|
spec.current.attrs
|
58
56
|
}
|
59
57
|
end
|
58
|
+
|
59
|
+
|
60
|
+
def test_queued_lock
|
61
|
+
q = Wakame::Service::LockQueue.new(nil)
|
62
|
+
q.set('Apache', '12345')
|
63
|
+
q.set('MySQL', '12345')
|
64
|
+
q.set('MySQL2', '12345')
|
65
|
+
q.set('Apache', '6789')
|
66
|
+
q.set('LB', '6789')
|
67
|
+
assert_equal(:runnable, q.test('12345'))
|
68
|
+
assert_equal(:wait, q.test('6789'))
|
69
|
+
assert_equal(:pass, q.test('unknown'))
|
70
|
+
#puts q.inspect
|
71
|
+
q.quit('12345')
|
72
|
+
assert_equal(:pass, q.test('12345'))
|
73
|
+
assert_equal(:runnable, q.test('6789'))
|
74
|
+
#puts q.inspect
|
75
|
+
q.set('Apache', '2345')
|
76
|
+
q.set('LB', '2345')
|
77
|
+
q.set('MySQL', '2345')
|
78
|
+
assert_equal(:runnable, q.test('6789'))
|
79
|
+
assert_equal(:wait, q.test('2345'))
|
80
|
+
q.quit('2345')
|
81
|
+
assert_equal(:runnable, q.test('6789'))
|
82
|
+
assert_equal(:pass, q.test('2345'))
|
83
|
+
end
|
60
84
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class Ec2ELB < Wakame::Service::Resource
|
2
|
+
|
3
|
+
def_attribute :elb_name, 'unakatsuo'
|
4
|
+
def_attribute :require_agent, false
|
5
|
+
def_attribute :just_unregister_when_stop, false
|
6
|
+
|
7
|
+
def on_parent_changed(svc, action)
|
8
|
+
end
|
9
|
+
|
10
|
+
def start(svc, action)
|
11
|
+
elb = create_elb
|
12
|
+
|
13
|
+
parents = svc.parent_instances.dup
|
14
|
+
|
15
|
+
vm_slice_ids = parents.collect{|a| a.agent.attr[:instance_id] }
|
16
|
+
av_zones = parents.collect{|a| a.agent.attr[:availability_zone] }.uniq
|
17
|
+
Wakame.log.info("Setting up the ELB #{self.elb_name} with #{vm_slice_ids.join(', ')}")
|
18
|
+
begin
|
19
|
+
res = elb.describe_load_balancers(self.elb_name)
|
20
|
+
elbdesc = res[0]
|
21
|
+
rescue RightAws::AwsError => e
|
22
|
+
if e.include?(/\ALoadBalancerNotFound\Z/)
|
23
|
+
|
24
|
+
elb.create_load_balancer(self.elb_name, av_zones,[{ :protocol => :http, :load_balancer_port => 80, :instance_port => 80 },
|
25
|
+
{ :protocol => :tcp, :load_balancer_port => 443, :instance_port => 443 } ])
|
26
|
+
else
|
27
|
+
Wakame.log.error(e.errors.inspect)
|
28
|
+
raise e
|
29
|
+
end
|
30
|
+
|
31
|
+
res = elb.describe_load_balancers(self.elb_name)
|
32
|
+
elbdesc = res[0]
|
33
|
+
end
|
34
|
+
|
35
|
+
elb_members, elb_not_members = vm_slice_ids.partition{|i| elbdesc[:instances].member?(i) }
|
36
|
+
unless elb_not_members.empty?
|
37
|
+
elb.register_instances_with_load_balancer(self.elb_name, *elb_not_members)
|
38
|
+
end
|
39
|
+
|
40
|
+
EM.barrier {
|
41
|
+
svc.update_status(Wakame::Service::STATUS_ONLINE)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def stop(svc, action)
|
46
|
+
elb = create_elb
|
47
|
+
|
48
|
+
if self.just_unregister_when_stop
|
49
|
+
parents = svc.parent_instances.dup
|
50
|
+
vm_slice_ids = parents.collect{|a| a.agent.attr[:instance_id] }
|
51
|
+
Wakame.log.info("Deregistering the VM instances (#{vm_slice_ids.join(', ')}) from ELB #{self.elb_name}")
|
52
|
+
|
53
|
+
elb.deregister_instances_with_load_balancer(self.elb_name, *vm_slice_id)
|
54
|
+
else
|
55
|
+
Wakame.log.info("Destroying the ELB #{self.elb_name}.")
|
56
|
+
# Ignore errors in case of any issues.
|
57
|
+
begin
|
58
|
+
elb.delete_load_balancer(self.elb_name)
|
59
|
+
rescue => e
|
60
|
+
Wakame.log.error(e)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
EM.barrier {
|
65
|
+
svc.update_status(Wakame::Service::STATUS_OFFLINE)
|
66
|
+
}
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def create_elb
|
72
|
+
require 'right_aws'
|
73
|
+
RightAws::ElbInterface.new(Wakame.config.aws_access_key, Wakame.config.aws_secret_key)
|
74
|
+
end
|
75
|
+
|
76
|
+
def setup_elb
|
77
|
+
elb = create_elb
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -19,6 +19,7 @@
|
|
19
19
|
[client]
|
20
20
|
port = <%= property.mysqld_port %>
|
21
21
|
socket = /var/run/mysqld/mysqld.sock
|
22
|
+
default-character-set = utf8
|
22
23
|
|
23
24
|
# Here is entries for some specific programs
|
24
25
|
# The following values assume you have at least 32M ram
|
@@ -47,6 +48,7 @@ basedir = /usr
|
|
47
48
|
datadir = <%= property.mysqld_datadir %>
|
48
49
|
tmpdir = /tmp
|
49
50
|
language = /usr/share/mysql/english
|
51
|
+
default-character-set = utf8
|
50
52
|
skip-external-locking
|
51
53
|
#
|
52
54
|
# Instead of skip-networking the default is now to listen only on
|
@@ -85,7 +87,7 @@ long_query_time = 2
|
|
85
87
|
# The following can be used as easy to replay backup logs or for replication.
|
86
88
|
# note: if you are setting up a replication slave, see README.Debian about
|
87
89
|
# other settings you may need to change.
|
88
|
-
server-id =
|
90
|
+
server-id = 1
|
89
91
|
log_bin = <%= property.mysqld_log_bin %>
|
90
92
|
#expire_logs_days = 10
|
91
93
|
#max_binlog_size = 100M
|
@@ -44,7 +44,7 @@ export HOME=/etc/mysql/
|
|
44
44
|
#
|
45
45
|
# Usage: void mysqld_get_param option
|
46
46
|
mysqld_get_param() {
|
47
|
-
/usr/sbin/mysqld --print-defaults \
|
47
|
+
/usr/sbin/mysqld --defaults-file=$CONF --print-defaults \
|
48
48
|
| tr " " "\n" \
|
49
49
|
| grep -- "--$1" \
|
50
50
|
| tail -n 1 \
|
@@ -114,8 +114,8 @@ case "${1:-''}" in
|
|
114
114
|
if mysqld_status check_alive warn; then
|
115
115
|
log_end_msg 0
|
116
116
|
# Now start mysqlcheck or whatever the admin wants.
|
117
|
-
output=$(/etc/mysql/debian-start)
|
118
|
-
[ -n "$output" ] && log_action_msg "$output"
|
117
|
+
#output=$(/etc/mysql/debian-start)
|
118
|
+
#[ -n "$output" ] && log_action_msg "$output"
|
119
119
|
else
|
120
120
|
log_end_msg 1
|
121
121
|
log_failure_msg "Please take a look at the syslog"
|
@@ -3,13 +3,15 @@ class MySQL_Master < Wakame::Service::Resource
|
|
3
3
|
|
4
4
|
def_attribute :duplicable, false
|
5
5
|
def_attribute :mysqld_basedir, '/home/wakame/mysql'
|
6
|
-
def_attribute :mysqld_server_id, 1
|
7
6
|
def_attribute :mysqld_port, 3306
|
8
7
|
|
9
8
|
def_attribute :ebs_volume, ''
|
10
9
|
def_attribute :ebs_device, '/dev/sdm'
|
11
10
|
def_attribute :ebs_mount_option, 'noatime'
|
12
11
|
|
12
|
+
def_attribute :repl_user, 'wakame-repl'
|
13
|
+
def_attribute :repl_pass, 'wakame-slave'
|
14
|
+
|
13
15
|
def basedir
|
14
16
|
File.join(Wakame.config.root_path, 'cluster', 'resources', 'mysql_master')
|
15
17
|
end
|
@@ -28,12 +30,7 @@ class MySQL_Master < Wakame::Service::Resource
|
|
28
30
|
template.chmod("init.d/mysql", 0755)
|
29
31
|
end
|
30
32
|
|
31
|
-
|
32
33
|
def start(svc, action)
|
33
|
-
vm_manipulator = Wakame::VmManipulator.create
|
34
|
-
|
35
|
-
# $ echo "GRANT REPLICATION SLAVE, REPLICATION CLIENT, RELOAD ON *.* TO 'wakame-repl'@'%' IDENTIFIED BY 'wakame-slave';" | /usr/bin/mysql -h#{mysql_master_ip} -uroot
|
36
|
-
|
37
34
|
require 'right_aws'
|
38
35
|
ec2 = RightAws::Ec2.new(Wakame.config.aws_access_key, Wakame.config.aws_secret_key)
|
39
36
|
|
@@ -69,7 +66,6 @@ class MySQL_Master < Wakame::Service::Resource
|
|
69
66
|
}
|
70
67
|
}
|
71
68
|
cond.wait
|
72
|
-
|
73
69
|
end
|
74
70
|
|
75
71
|
cond = ConditionalWait.new { |cond|
|
@@ -84,6 +80,11 @@ class MySQL_Master < Wakame::Service::Resource
|
|
84
80
|
:command, "/usr/bin/mysqladmin --defaults-file=#{svc.agent.root_path}/tmp/config/mysql_master/conf/my.cnf ping > /dev/null") { |req|
|
85
81
|
}
|
86
82
|
|
83
|
+
action.actor_request(svc.agent.agent_id, '/system/sync') { |req|
|
84
|
+
req.wait
|
85
|
+
Wakame.log.debug("sync")
|
86
|
+
}
|
87
|
+
|
87
88
|
action.actor_request(svc.agent.agent_id, '/system/mount', self.ebs_device, self.mysqld_datadir, self.ebs_mount_option) { |req|
|
88
89
|
req.wait
|
89
90
|
Wakame.log.debug("MySQL volume was mounted: #{self.mysqld_datadir}")
|
@@ -98,18 +99,16 @@ class MySQL_Master < Wakame::Service::Resource
|
|
98
99
|
end
|
99
100
|
|
100
101
|
def stop(svc, action)
|
101
|
-
cond = ConditionalWait.new { |
|
102
|
-
|
102
|
+
cond = ConditionalWait.new { |c|
|
103
|
+
c.wait_event(Wakame::Event::ServiceOffline) { |event|
|
103
104
|
event.instance_id == svc.instance_id
|
104
105
|
}
|
105
|
-
}
|
106
|
-
|
106
|
+
}
|
107
107
|
action.actor_request(svc.agent.agent_id, '/daemon/stop', 'mysql_master', 'init.d/mysql') { |req| req.wait }
|
108
108
|
action.actor_request(svc.agent.agent_id, '/system/umount', self.mysqld_datadir) { |req|
|
109
109
|
req.wait
|
110
110
|
Wakame.log.debug("MySQL volume unmounted")
|
111
111
|
}
|
112
|
-
|
113
112
|
cond.wait
|
114
113
|
|
115
114
|
action.actor_request(svc.agent.agent_id,
|