ey_cloud_server 1.2.3 → 1.3.1

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/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: []