Skip to content

Commit

Permalink
fix mysql rollback from snapshot function
Browse files Browse the repository at this point in the history
1. handle sepcial characters in username and password.
2. prevent import data using root user.

Change-Id: Iff9de0e4ab1802d791e5cb611fb96f44d9daf0a7
  • Loading branch information
Andrew Liu committed Aug 21, 2012
1 parent 878a712 commit 79bfc4c
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 7 deletions.
20 changes: 19 additions & 1 deletion mysql/lib/mysql_service/job/mysql_snapshot.rb
Expand Up @@ -3,13 +3,25 @@
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..')
require "util"
require "mysql_error"
require "datamapper_l"

module VCAP::Services::Mysql::Snapshot
include VCAP::Services::Base::AsyncJob::Snapshot

module Common
def init_localdb(database_url)
DataMapper.setup(:default, database_url)
end

def mysql_provisioned_service
VCAP::Services::Mysql::Node::ProvisionedService
end
end

# Dump a database into files and save the snapshot information into redis.
class CreateSnapshotJob < BaseCreateSnapshotJob
include VCAP::Services::Mysql::Util
include Common

def execute
dump_path = get_dump_path(name, snapshot_id)
Expand Down Expand Up @@ -39,15 +51,21 @@ def execute
# Rollback data from snapshot files.
class RollbackSnapshotJob < BaseRollbackSnapshotJob
include VCAP::Services::Mysql::Util
include Common

def execute
init_localdb(@config["local_db"])
srv = mysql_provisioned_service.get(name)
instance_user = srv.user
instance_pass = srv.password

mysql_conf = @config["mysql"]
snapshot_file_path = @snapshot_files[0]
raise "Can't find snapshot file #{snapshot_file_path}" unless File.exists?(snapshot_file_path)
manifest = @manifest
@logger.debug("Manifest for snapshot: #{manifest}")

result = import_dumpfile(name, mysql_conf, mysql_conf["user"], mysql_conf["pass"], snapshot_file_path, :mysql_bin => @config["mysql_bin"], :gzip_bin => @config["gzip_bin"])
result = import_dumpfile(name, mysql_conf, instance_user, instance_pass, snapshot_file_path, :mysql_bin => @config["mysql_bin"], :gzip_bin => @config["gzip_bin"])
raise "Failed execute import command to #{name}" unless result

true
Expand Down
6 changes: 3 additions & 3 deletions mysql/lib/mysql_service/node.rb
Expand Up @@ -476,7 +476,7 @@ def restore(name, backup_path)
host, user, pass, port, socket = %w{host user pass port socket}.map { |opt| @mysql_config[opt] }
path = File.join(backup_path, "#{name}.sql.gz")
cmd = "#{@gzip_bin} -dc #{path}|" +
"#{@mysql_bin} -h #{host} -P #{port} -u #{user} --password=#{pass}"
"#{@mysql_bin} -h #{host} -P #{port} --user='#{user}' --password='#{pass}'"
cmd += " -S #{socket}" unless socket.nil?
cmd += " #{name}"
o, e, s = exe_cmd(cmd)
Expand Down Expand Up @@ -514,7 +514,7 @@ def dump_instance(prov_cred, binding_creds, dump_file_path)
host, user, password, port, socket = %w{host user pass port socket}.map { |opt| @mysql_config[opt] }
dump_file = File.join(dump_file_path, "#{name}.sql")
@logger.info("Dump instance #{name} content to #{dump_file}")
cmd = "#{@mysqldump_bin} -h #{host} -u #{user} --password=#{password} -R --single-transaction #{'-S '+socket if socket} #{name} > #{dump_file}"
cmd = "#{@mysqldump_bin} -h #{host} --user='#{user}' --password='#{password}' -R --single-transaction #{'-S '+socket if socket} #{name} > #{dump_file}"
o, e, s = exe_cmd(cmd)
if s.exitstatus == 0
return true
Expand All @@ -536,7 +536,7 @@ def import_instance(prov_cred, binding_creds_hash, dump_file_path, plan)
import_file = File.join(dump_file_path, "#{name}.sql")
host, user, password, port, socket = %w{host user pass port socket}.map { |opt| @mysql_config[opt] }
@logger.info("Import data from #{import_file} to database #{name}")
cmd = "#{@mysql_bin} --host=#{host} --user=#{user} --password=#{password} #{'-S '+socket if socket} #{name} < #{import_file}"
cmd = "#{@mysql_bin} --host=#{host} --user='#{user}' --password='#{password}' #{'-S '+socket if socket} #{name} < #{import_file}"
o, e, s = exe_cmd(cmd)
if s.exitstatus == 0
# delete the procedures and functions: security_type is definer while the definer doesn't exist
Expand Down
4 changes: 2 additions & 2 deletions mysql/lib/mysql_service/util.rb
Expand Up @@ -40,7 +40,7 @@ def dump_database(db, mysql_config, dump_file_path, opts={})
gzip_bin = opts[:gzip_bin] || "gzip"

socket_str = "-S #{socket}"
cmd = "#{mysql_dump_bin} -h#{host} -u#{user} -p#{password} -P#{port} #{socket_str if socket} -R --single-transaction #{db}| #{gzip_bin} - > #{dump_file_path}"
cmd = "#{mysql_dump_bin} -h#{host} --user='#{user}' --password='#{password}' -P#{port} #{socket_str if socket} -R --single-transaction #{db}| #{gzip_bin} - > #{dump_file_path}"
@logger.info("Take snapshot command:#{cmd}")

on_err = Proc.new do |cmd, code, msg|
Expand Down Expand Up @@ -95,7 +95,7 @@ def import_dumpfile(db, mysql_config, import_user, import_pass, dump_file_path,
restore_privileges(db) if @connection

socket_str = "-S #{socket}"
cmd = "#{gzip_bin} -dc #{dump_file_path}| #{mysql_bin} -h#{host} -P#{port} -u#{import_user} -p#{import_pass} #{socket_str if socket} #{db}"
cmd = "#{gzip_bin} -dc #{dump_file_path}| #{mysql_bin} -h#{host} -P#{port} --user='#{import_user}' --password='#{import_pass}' #{socket_str if socket} #{db}"
@logger.info("import dump file cmd: #{cmd}")
on_err = Proc.new do |cmd, code, msg|
raise "CMD '#{cmd}' exit with code: #{code}. Message: #{msg}"
Expand Down
2 changes: 1 addition & 1 deletion mysql/spec/mysql_node_spec.rb
Expand Up @@ -464,7 +464,7 @@ class MysqlError
host, port, user, password = %w(host port user pass).map{|key| @opts[:mysql][key]}
tmp_file = "/tmp/#{db['name']}.sql.gz"
@tmpfiles << tmp_file
result = `mysqldump -h #{host} -P #{port} -u #{user} --password=#{password} -R #{db['name']} | gzip > #{tmp_file}`
result = `mysqldump -h #{host} -P #{port} --user='#{user}' --password='#{password}' -R #{db['name']} | gzip > #{tmp_file}`
bind_conn.query("drop procedure myfunc")
conn.query("drop table test")
res = bind_conn.query("show procedure status")
Expand Down

0 comments on commit 79bfc4c

Please sign in to comment.