Class: Reptile::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/reptile/runner.rb

Overview

The runner class is responsible for running command on each slave. The commands are run sequentially, no guaranteed order (though probably from yml file).

Class Method Summary collapse

Class Method Details

.connect(configs) ⇒ Object

Tries to establish a database connection, and returns that connection. Dumps configs on error.



49
50
51
52
53
54
55
56
# File 'lib/reptile/runner.rb', line 49

def self.connect(configs)
  ActiveRecord::Base.establish_connection(configs)
  ActiveRecord::Base.connection
rescue Exception => e
  Log.error "Error connecting to database: #{e}"
  Log.error YAML::dump(configs)
  exit 1
end

.databasesObject

The databases to run commands upon.



22
23
24
# File 'lib/reptile/runner.rb', line 22

def self.databases
  @databases
end

.databases=(databases) ⇒ Object

Set the databases to run command upon.



17
18
19
# File 'lib/reptile/runner.rb', line 17

def self.databases=(databases)
  @databases = databases
end

.execute_on_slaves(cmd, configs = {}) ⇒ Object

Executes a command on all the slaves, sequentially. Takes an optional set of connection paramters to override defaults.



60
61
62
63
64
65
66
67
# File 'lib/reptile/runner.rb', line 60

def self.execute_on_slaves(cmd, configs={})
  slaves.each do |name, slave_configs|
    Log.info "Executing #{cmd} on #{name}"
    Log.info slave_configs.inspect
    connection = connect(slave_configs.merge(user).merge(configs))
    connection.execute(cmd)
  end
end

.setupObject

Creates users with specific permissions on the different mysql servers, both masters and slaves. Prompts for username and password of an account that has GRANT priviledges.



81
82
83
84
85
86
87
88
89
90
# File 'lib/reptile/runner.rb', line 81

def self.setup
  raise "GET CONFIGS"
  grant_user_configs = User.prompt_for_grant_user
  # TODO: use specific tables, not *.*
  # TODO: are these on localhost? or where?
  # TODO: We need all databases in order to grant permissions there.
  # TODO: There could be a different GRANT password for each mysql server, so identify which before asking for permissions.
  execute_on_slaves("GRANT select ON *.* TO #{ro_user}@???? INDENTIFIED BY #{ro_password}", grant_user_configs)
  execute_on_slaves("GRANT select ON *.* TO #{repl_user}@???? INDENTIFIED BY #{repl_password}", grant_user_configs)
end

.setup_heartbeatObject



92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/reptile/runner.rb', line 92

def self.setup_heartbeat
  # MySQL DTD for setting up Heartbeats.  Change HEARTBEAT_USER, HEARTBEAT_PASS, and MONITORING_BOX to ip of the monitoring server.
  # GRANT SELECT, INSERT, UPDATE, ALTER ON replication_monitor.* TO 'HEARTBEAT_USER'@"localhost" IDENTIFIED BY 'HEARTBEAT_PASS';
  # GRANT SELECT, INSERT, UPDATE, ALTER ON replication_monitor.* TO 'HEARTBEAT_USER'@"MONITORING_BOX" IDENTIFIED BY 'HEARTBEAT_PASS';
  #
  # CREATE DATABASE replication_monitor;
  #
  # CREATE TABLE replication_monitor.heartbeats (
  #   unix_time INTEGER NOT NULL,
  #   db_time TIMESTAMP NOT NULL,
  #   INDEX time_idx(unix_time)
  # )
end

.slavesObject

The slaves to run commands upon.



41
42
43
44
# File 'lib/reptile/runner.rb', line 41

def self.slaves
  raise "You need to specify the slaves to run against!" if @slaves.nil?
  @slaves
end

.slaves=(slaves) ⇒ Object

Set the slaves to run command upon.



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/reptile/runner.rb', line 27

def self.slaves=(slaves)
  slaves.each do |name, configs|
    configs.delete('port')
    configs.delete('host')
    # With activeRecord, you have to connect to some DB, even if you are acting on the server...
    configs['database'] = 'information_schema' unless configs['database']
    # TODO: Delete these somewhere else
    configs.delete('heartbeat')
    configs.delete('replication_user')
  end
  @slaves = slaves
end

.start_slavesObject

Execute START SLAVE on all slaves.



75
76
77
# File 'lib/reptile/runner.rb', line 75

def self.start_slaves
  execute_on_slaves("START SLAVE;")
end

.stop_slavesObject

Execute STOP SLAVE on all slaves;



70
71
72
# File 'lib/reptile/runner.rb', line 70

def self.stop_slaves
  execute_on_slaves("STOP SLAVE;")
end

.test_connectionsObject



106
107
108
109
110
111
112
# File 'lib/reptile/runner.rb', line 106

def self.test_connections
  databases.each do |db|
    databases.roles.each do |role|
      db[role]
    end
  end
end

.userObject

The user settings for a user that has REPLICATION SLAVE privilidgess



11
12
13
14
# File 'lib/reptile/runner.rb', line 11

def self.user
  raise "You need to specify a replication user!" if @repl_user.nil?
  @repl_user
end

.user=(replication_user_settings) ⇒ Object

Set the user settings for a user that has REPLICATION SLAVE privilidgess



6
7
8
# File 'lib/reptile/runner.rb', line 6

def self.user=()
  @repl_user = 
end