ey_cloud_server 1.2.3 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/mysql_start ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__) + '/../lib'
4
+ require 'ey_cloud_server'
5
+
6
+ EY::CloudServer::MysqlStart.run(ARGV)
@@ -1,3 +1,3 @@
1
1
  module EY::CloudServer
2
- VERSION = '1.1.0'
2
+ VERSION = '1.3.1'
3
3
  end
@@ -0,0 +1,9 @@
1
+ require "optparse"
2
+
3
+ module EY
4
+ module CloudServer
5
+ end
6
+ end
7
+
8
+ require 'ey-flex/version'
9
+ require 'ey_cloud_server/mysql_start'
@@ -0,0 +1,148 @@
1
+ module EY
2
+ module CloudServer
3
+ class MysqlStart
4
+ def self.run(argv = ARGV, options = {})
5
+ options = parse(argv, options)
6
+ new(options).run
7
+ end
8
+
9
+ attr_accessor :password, :check, :timeout
10
+
11
+ def initialize(options = {})
12
+ @password = options[:password] || abort("ERROR: You must provide a password.")
13
+ @check = options[:check] || abort("ERROR: You must a check interval.")
14
+ @timout = options[:timeout] || abort("ERROR: You must provide a timeout.")
15
+
16
+ abort("ERROR: You must be root.") unless Process.euid == 0
17
+ end
18
+
19
+ def run
20
+ count = 0
21
+ if system('/etc/init.d/mysql restart')
22
+ mysql_started()
23
+ else
24
+ log_mysql_event("MySQL did not start within the startup timeout")
25
+ loop {
26
+ # test to make sure mysql is running
27
+ if mysql_running()
28
+ log_mysql_event("MySQL did start and is working through crash recovery")
29
+ sleeptime = check
30
+ slept = 0
31
+ sleeplimit = timeout
32
+ loop {
33
+ if system("mysqladmin -p#{password} status") # mysql is accessible
34
+ log_mysql_event("MySQL completed crash recovery, performing clean restart")
35
+ system('killall -TERM mysqld') # safe shutdown of mysql
36
+ termslept = 0
37
+ termlimit = 120
38
+ loop {
39
+ break if not mysql_running()
40
+ sleep(sleeptime)
41
+ termslept = termslept + sleeptime
42
+ if termslept > termlimit
43
+ log_mysql_event("MySQL did not shut down cleanly within the time limit, killing")
44
+ system('killall -9 mysqld')
45
+ end
46
+ }
47
+ system('/etc/init.d/mysql zap') # clear files
48
+ if system('/etc/init.d/mysql restart') # clean start
49
+ mysql_started()
50
+ end
51
+ else
52
+ log_mysql_event("MySQL has been starting for #{slept/60} minutes and is still attempting to start") if slept % 120 == 0
53
+ sleep(sleeptime)
54
+ end
55
+ break if not mysql_running()
56
+ slept = slept + sleeptime
57
+ if slept > sleeplimit
58
+ log_mysql_event("MySQL was not able to start after #{slept/60} minutes and was forcibly killed")
59
+ system("killall -9 mysqld")
60
+ end
61
+ }
62
+ else
63
+ log_mysql_event("MySQL did not start, zapping")
64
+ begin
65
+ pidfile = '/var/run/mysqld/mysqld.pid'
66
+ if File.exists?(pidfile)
67
+ File.open('/var/run/mysqld/mysqld.pid', 'r') do |f|
68
+ pid = f.read.to_i
69
+ Process.kill("TERM", pid)
70
+
71
+ mysqld_is_dead = false
72
+ started_at = Time.now
73
+ # /etc/init.d/mysql has 120 as STOPTIMEOUT, so we should
74
+ # wait at least that long
75
+ until mysqld_is_dead || ((Time.now - started_at) > 120)
76
+ begin
77
+ Process.kill(0, pid)
78
+ sleep 1
79
+ rescue Errno::ESRCH # no such process
80
+ mysqld_is_dead = true
81
+ end
82
+ end
83
+ end
84
+ end
85
+ rescue Exception => e
86
+ File.open('/root/chef-mysql.log', 'a') do |f|
87
+ f.write("Blew up: \n")
88
+ f.write(e.message)
89
+ f.write("\n")
90
+ f.write(e.backtrace.join("\t\n"))
91
+ end
92
+ end
93
+ system('/etc/init.d/mysql zap')
94
+ if system('/etc/init.d/mysql restart')
95
+ mysql_started()
96
+ end
97
+ end
98
+ count += 1
99
+ if count > 10
100
+ log_mysql_event("Failed to start mysql after 10 attempts, raising error.")
101
+ exit(1)
102
+ end
103
+ sleep 1
104
+ }
105
+ end
106
+ end
107
+
108
+ def log_mysql_event(message)
109
+ `echo #{message} >> /root/chef-mysql.log`
110
+ end
111
+
112
+ def mysql_started()
113
+ log_mysql_event("MySQL restarted successfully")
114
+ exit 0
115
+ end
116
+
117
+ def mysql_running()
118
+ system("ps -u mysql | grep '[m]ysqld'")
119
+ end
120
+
121
+ def self.parse(argv, options = {})
122
+ opts = OptionParser.new do |opts|
123
+ opts.version = VERSION
124
+
125
+ opts.banner = "Usage: mysql_start [-flag]"
126
+ opts.define_head "mysql_start: start, recover, zap, or otherwise pound mysql into submission."
127
+ opts.separator '*'*80
128
+
129
+ opts.on("-p", "--password PASSWORD", "Root password for mysqladmin.") do |password|
130
+ options[:password] = password
131
+ end
132
+
133
+ opts.on("-c", "--check NUMBER", "Check mysql interval in seconds.") do |check|
134
+ options[:check] = check.to_i
135
+ end
136
+
137
+ opts.on("-t", "--timeout NUMBER", "Maximum wait time in seconds.") do |timeout|
138
+ options[:timeout] = timeout.to_i
139
+ end
140
+ end
141
+
142
+ opts.parse!(argv)
143
+
144
+ options
145
+ end
146
+ end
147
+ end
148
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 2
8
7
  - 3
9
- version: 1.2.3
8
+ - 1
9
+ version: 1.3.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Engine Yard Engineers
@@ -100,6 +100,7 @@ executables:
100
100
  - eybackup
101
101
  - ey-snapshots
102
102
  - ey-agent
103
+ - mysql_start
103
104
  extensions: []
104
105
 
105
106
  extra_rdoc_files: []
@@ -114,9 +115,12 @@ files:
114
115
  - lib/ey-flex/snapshot_minder.rb
115
116
  - lib/ey-flex/version.rb
116
117
  - lib/ey-flex.rb
118
+ - lib/ey_cloud_server/mysql_start.rb
119
+ - lib/ey_cloud_server.rb
117
120
  - bin/eybackup
118
121
  - bin/ey-snapshots
119
122
  - bin/ey-agent
123
+ - bin/mysql_start
120
124
  has_rdoc: true
121
125
  homepage: http://github.com/engineyard
122
126
  licenses: []