mysql-slaver 0.1.9 → 0.1.10

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/README.md CHANGED
@@ -14,7 +14,7 @@ ASSUMPTIONS/PRE-REQUISITES
14
14
 
15
15
  * localhost is configured as a mysql replication slave
16
16
  * the current localhost user can ssh to the db master
17
- * any ssh config settings required to access the master from localhost are set in a ~/.ssh/config file
17
+ * any ssh config settings, other than a port number, required to access the master from localhost are set in a ~/.ssh/config file
18
18
  * ssh is on the current user's path
19
19
  * your mysql administrator user is called 'root', locally and on the db master
20
20
  * mysql is on the local user's path
@@ -30,11 +30,10 @@ CAVEATS
30
30
 
31
31
  TODO
32
32
 
33
- * add a "no copying" mode that only updates master log file and position
33
+ * output better help (include optional params, format better (shorter lines))
34
34
  * add a "dry-run" mode
35
- * check ssh connection and permissions
35
+ * check ssh connection
36
36
  * check replication permissions
37
37
  * check slave is setup as a replication slave (i.e. it has a mysql server id)
38
38
  * allow a mysql admin username other than 'root'
39
39
  * allow different root user passwords on slave and master
40
- * allow ssh options
@@ -1,21 +1,24 @@
1
1
  module MysqlSlaver
2
2
  class CLI < ::Thor
3
+ desc "enslave", "Start MySQL replication to this host from a master"
4
+
3
5
  option :master_host, :required => true, :desc => "The server which will be the replication master, for this slave"
4
6
  option :database, :required => true, :desc => "The database to copy from the master"
5
7
  option :replication_user, :required => true, :desc => "DB user (on the master host), with replication permissions"
6
8
  option :replication_password, :required => true, :desc => "DB password for the replication user"
7
-
8
9
  option :root_password, :desc => "Password for the mysql root user (on both master and slave)"
9
10
  option :port, :desc => "Mysql port (if not 3306)"
11
+ option :ssh_port, :desc => "SSH port (if not 22)"
10
12
  option :sock, :desc => "Mysql socket file (if any)"
11
-
12
- desc "enslave", "start mysql replication to this host from a master"
13
+ option :no_copy, :type => :boolean, :desc => "Do not copy data - just change master status"
13
14
 
14
15
  def enslave
15
16
  MysqlSlaver::Slaver.new(
16
17
  :master_host => options[:master_host],
17
18
  :port => options[:port],
19
+ :ssh_port => options[:ssh_port],
18
20
  :socket_file => options[:sock],
21
+ :no_copy => options[:no_copy],
19
22
  :mysql_root_password => options[:root_password],
20
23
  :database => options[:database],
21
24
  :replication_user => options[:replication_user],
@@ -10,7 +10,7 @@ module MysqlSlaver
10
10
  @database = params.fetch(:database)
11
11
  @port = params.fetch(:port, nil)
12
12
  @socket_file = params.fetch(:socket_file, nil)
13
- @executor = params.fetch(:executor) { Executor.new }
13
+ @executor = params.fetch(:executor) { Executor.new(:ssh_port => params[:ssh_port]) }
14
14
  end
15
15
 
16
16
  def copy!
@@ -1,9 +1,19 @@
1
1
  module MysqlSlaver
2
2
  class Executor
3
+ attr_reader :ssh_port
4
+
3
5
  include Logger
4
6
 
7
+ def initialize(params = {})
8
+ @ssh_port = params[:ssh_port]
9
+ end
10
+
5
11
  def ssh_command(cmd, host)
6
- "ssh #{host} '#{cmd}'"
12
+ if ssh_port
13
+ "ssh -p #{ssh_port} #{host} '#{cmd}'"
14
+ else
15
+ "ssh #{host} '#{cmd}'"
16
+ end
7
17
  end
8
18
 
9
19
  def execute(cmd)
@@ -6,18 +6,21 @@
6
6
  # connection)
7
7
  module MysqlSlaver
8
8
  class Slaver
9
- attr_reader :status_fetcher, :data_copier, :master_changer
9
+ attr_reader :status_fetcher, :data_copier, :master_changer, :no_copy
10
10
 
11
11
  def initialize(params)
12
12
  mysql_root_password = params.fetch(:mysql_root_password, '')
13
13
  port = params.fetch(:port, 3306)
14
+ ssh_port = params.fetch(:ssh_port, 22)
14
15
  socket_file = params.fetch(:socket_file, nil)
16
+ @no_copy = params.fetch(:no_copy, false)
15
17
 
16
18
  @status_fetcher = params.fetch(:status_fetcher) {
17
19
  StatusFetcher.new(
18
20
  :master_host => params.fetch(:master_host),
19
21
  :mysql_root_password => mysql_root_password,
20
- :socket_file => socket_file
22
+ :socket_file => socket_file,
23
+ :ssh_port => ssh_port
21
24
  )
22
25
  }
23
26
 
@@ -27,7 +30,8 @@ module MysqlSlaver
27
30
  :mysql_root_password => mysql_root_password,
28
31
  :database => params.fetch(:database),
29
32
  :port => port,
30
- :socket_file => socket_file
33
+ :socket_file => socket_file,
34
+ :ssh_port => ssh_port
31
35
  )
32
36
  }
33
37
 
@@ -45,7 +49,7 @@ module MysqlSlaver
45
49
 
46
50
  def enslave!
47
51
  master_status = status_fetcher.status
48
- data_copier.copy!
52
+ data_copier.copy! unless no_copy
49
53
  master_changer.change!(master_status)
50
54
  end
51
55
  end
@@ -9,7 +9,7 @@ module MysqlSlaver
9
9
  @master_host = params.fetch(:master_host)
10
10
  @socket_file = params.fetch(:socket_file, nil)
11
11
  @mysql_root_password = params.fetch(:mysql_root_password, '')
12
- @executor = params.fetch(:executor) { Executor.new }
12
+ @executor = params.fetch(:executor) { Executor.new(:ssh_port => params[:ssh_port]) }
13
13
  end
14
14
 
15
15
  def status
@@ -2,12 +2,23 @@ require 'spec/spec_helper'
2
2
 
3
3
  module MysqlSlaver
4
4
  describe Executor do
5
- subject(:executor) { described_class.new }
5
+ let(:ssh_port) { nil }
6
+ let(:params) { {:ssh_port => ssh_port} }
7
+
8
+ subject(:executor) { described_class.new(params) }
6
9
 
7
10
  describe "#ssh_command" do
8
11
  it "formats command" do
9
12
  expect(executor.ssh_command("foo", "myhost")).to eq("ssh myhost 'foo'")
10
13
  end
14
+
15
+ context "with non-standard ssh port" do
16
+ let(:ssh_port) { 64389 }
17
+
18
+ it "formats command" do
19
+ expect(executor.ssh_command("foo", "myhost")).to eq("ssh -p 64389 myhost 'foo'")
20
+ end
21
+ end
11
22
  end
12
23
  end
13
24
  end
@@ -32,6 +32,24 @@ module MysqlSlaver
32
32
  expect(master_changer).to have_received(:change!)
33
33
  end
34
34
 
35
+ context "no-copy" do
36
+ let(:params) { super().merge(:no_copy => true) }
37
+
38
+ it "fetches master status" do
39
+ slaver.enslave!
40
+ expect(status_fetcher).to have_received(:status)
41
+ end
42
+
43
+ it "doesn't copy data" do
44
+ slaver.enslave!
45
+ expect(data_copier).to_not have_received(:copy!)
46
+ end
47
+
48
+ it "changes master status" do
49
+ slaver.enslave!
50
+ expect(master_changer).to have_received(:change!)
51
+ end
52
+ end
35
53
  end
36
54
 
37
55
  context "instantiating collaborators" do
@@ -76,6 +94,20 @@ module MysqlSlaver
76
94
  end
77
95
  end
78
96
 
97
+ context "with non-standard ssh port" do
98
+ let(:params) { super().merge(:ssh_port => 64389) }
99
+
100
+ it "instantiates a status fetcher" do
101
+ fetcher = slaver.status_fetcher
102
+ expect(fetcher.executor.ssh_port).to eq(64389)
103
+ end
104
+
105
+ it "instantiates a data copier" do
106
+ copier = slaver.data_copier
107
+ expect(copier.executor.ssh_port).to eq(64389)
108
+ end
109
+ end
110
+
79
111
  context "with mysql socket" do
80
112
  let(:params) { super().merge(:socket_file => "/tmp/mysql.sock") }
81
113
 
@@ -93,7 +125,6 @@ module MysqlSlaver
93
125
  copier = slaver.data_copier
94
126
  expect(copier.socket_file).to eq("/tmp/mysql.sock")
95
127
  end
96
-
97
128
  end
98
129
  end
99
130
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql-slaver
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 9
10
- version: 0.1.9
9
+ - 10
10
+ version: 0.1.10
11
11
  platform: ruby
12
12
  authors:
13
13
  - David Salgado
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2014-04-18 00:00:00 Z
18
+ date: 2014-04-20 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec