snapback 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,156 +0,0 @@
1
- require "lvm"
2
- require "singleton"
3
-
4
- module Snapback
5
- module App
6
- class Install
7
- include Singleton
8
-
9
- def go
10
- puts ""
11
- puts "Hi!"
12
- puts ""
13
- puts "I'm going to guide you through setting up Snapback."
14
- puts "This script will check to see if your environment can run "
15
- puts "Snapback and will setup configuration files for you."
16
- puts ""
17
-
18
- begin
19
- run "Checking LVM is installed",
20
- "lvm version"
21
- rescue
22
- raise "You do not have LVM installed on this computer. You cannot use snapback."
23
- end
24
-
25
- # Get information from LVM
26
- lvm = LVM::LVM.new({:command => "sudo lvm", :version => "2.02.30"})
27
- volume_groups = []
28
- volume_group = nil
29
-
30
- lvm.volume_groups.each do |vg|
31
- volume_groups.push(vg)
32
- end
33
- puts ""
34
-
35
- # Decide which Logical volume use to use
36
- if volume_groups.size == 0 then
37
- raise "You do not have any volume groups in LVM. Please setup LVM before using Snapback"
38
- elsif volume_groups.size == 1 then
39
- volume_group = volume_groups[0];
40
- puts "You have one volume group named #{volume_group.name.green}."
41
- puts "Snapback will use this logical volume."
42
- else
43
- puts "Here is a list of volume groups on your system:"
44
-
45
- volume_groups.each do |vg|
46
- puts "#{volume_groups.size}.\t#{vg.name}"
47
- end
48
-
49
- volume_group_number = ask_int "Which volume group would you like Snapback use", volume_groups.size
50
- volume_group = volume_groups[volume_group_number - 1];
51
- end
52
-
53
- puts ""
54
-
55
- # Check for mount directory
56
- mysql_mount_dir = ask_string "Where do you want to mount your logical volumes [/mnt/mysql]"
57
- puts ""
58
-
59
- if mysql_mount_dir.empty? then
60
- mysql_mount_dir = "/mnt/mysql"
61
- end
62
-
63
- if !check "Checking for directory #{mysql_mount_dir}", lambda {
64
- File.directory? mysql_mount_dir
65
- } then
66
- run "Creating directory #{mysql_mount_dir}",
67
- "mkdir -p #{mysql_mount_dir}"
68
-
69
- on_rollback lambda {
70
- run "Removing #{mysql_mount_dir} directory",
71
- "rm -rf #{mysql_mount_dir}"
72
- }
73
- end
74
-
75
- # MySQL connection
76
-
77
- while true
78
- puts ""
79
- puts "Enter the crudentials to connect to MySQL"
80
-
81
- $database = Snapback::Database.instance
82
-
83
- $database.hostname = ask_string "MySQL hostname [localhost]"
84
- if $database.hostname.empty? then
85
- $database.hostname = "localhost"
86
- end
87
-
88
- $database.username = ask_string "MySQL username [root]"
89
- if $database.username.empty? then
90
- $database.username = "root"
91
- end
92
-
93
- $database.password = ask_string "MySQL password"
94
-
95
- puts ""
96
-
97
- begin
98
- check "Connecting to MySQL database", lambda {
99
- $database.connect
100
- true
101
- }
102
- rescue
103
- show_failed
104
- next
105
- end
106
-
107
- break
108
- end
109
-
110
- if !check "Checking #{"innodb_file_per_table"} is #{"ON"}", lambda {
111
- $database.innodb_file_per_table
112
- } then
113
- debug "Setting #{"innodb_file_per_table"} to #{"ON"}"
114
- $database.set_innodb_file_per_table true
115
-
116
- on_rollback lambda {
117
- debug "Setting #{"innodb_file_per_table"} to #{"OFF"}"
118
- $database.set_innodb_file_per_table false
119
- }
120
- end
121
-
122
- $config = {
123
- 'lvm' => {
124
- 'volume_group' => volume_group.name.to_s,
125
- 'prefix_database' => 'snapback-active',
126
- 'prefix_backup' => 'snapback-backup'
127
- },
128
-
129
- 'mysql' => {
130
- 'hostname' => $database.hostname,
131
- 'username' => $database.username,
132
- 'password' => $database.password
133
- },
134
-
135
- 'filesystem' => {
136
- 'mount' => '/mnt/mysql'
137
- }
138
- }
139
-
140
- File.open($options[:config], 'w+') { |f|
141
- f.write($config.to_yaml)
142
- }
143
-
144
- on_rollback lambda {
145
- File.unlink $options[:config]
146
- }
147
-
148
- puts ""
149
- puts "Snapback is now installed and configured."
150
- puts "To start using Snapback, run the following command: "
151
- puts ""
152
- puts "sudo snapback --help".yellow
153
- end
154
- end
155
- end
156
- end
@@ -1,62 +0,0 @@
1
- require "singleton"
2
-
3
- module Snapback
4
- module App
5
- class Mount
6
- include Singleton
7
-
8
- def go
9
- volume_group_name = "#{$config['lvm']['volume_group']}"
10
- logical_volume_name = "#{$config['lvm']['prefix_database']}-#{$options[:database]}"
11
- mount_dir = get_mount_dir $options[:database]
12
- mysql_data_dir = $database.get_data_dir
13
-
14
- exec_flush
15
-
16
- # Stop the MySQL Server
17
- $database.server_stop
18
-
19
- on_rollback lambda {
20
- $database.server_start
21
- }
22
-
23
- # Create a new directory for where the MySQL database can be mounted
24
- # mkdir /mnt/mysql/{dbName};
25
-
26
- if !File.directory? mount_dir then
27
- run "Make mount directory",
28
- "mkdir #{mount_dir}"
29
-
30
- on_rollback lambda {
31
- run "Removing mount directory",
32
- "rmdir #{$mount_dir}"
33
- }
34
-
35
- run "Changing permissions of mount directory",
36
- "chmod 0777 #{mount_dir}"
37
- end
38
-
39
- # # Mount the new logical volume
40
- # mount /dev/{vgName}/mysql-{dbName} /mnt/mysql/{dbName};
41
- exec_mount "/dev/#{volume_group_name}/#{logical_volume_name}", mount_dir
42
-
43
- # # Symbolic-link the MySQL data directory to the new logical volume
44
- # ln -s /mnt/mysql/{dbName} {mysql-data-dir}/{dbName}/
45
- exec_link "#{mysql_data_dir}/#{$options[:database]}", mount_dir
46
-
47
- # # Change the permissions & ownership to MySQL
48
- # chown -R mysql:mysql {mysql-data-dir}/{dbName}/
49
- # chown -R mysql:mysql /mnt/mysql/{dbName}/
50
- exec_chown "#{mysql_data_dir}/#{$options[:database]}"
51
- exec_chown mount_dir
52
-
53
- # Stop the MySQL Server
54
- $database.server_start
55
-
56
- on_rollback lambda {
57
- $database.server_stop
58
- }
59
- end
60
- end
61
- end
62
- end
@@ -1,63 +0,0 @@
1
- require "singleton"
2
-
3
- module Snapback
4
- module App
5
- class Rollback
6
- include Singleton
7
-
8
- def go
9
- volume_group_name = "#{$config['lvm']['volume_group']}"
10
- logical_volume_name = "#{$config['lvm']['prefix_database']}-#{$options[:database]}"
11
- mount_dir = get_mount_dir $options[:database]
12
- mysql_data_dir = $database.get_data_dir
13
-
14
- # Flush the MySQL Logs
15
- exec_flush
16
-
17
- # Stop the MySQL Server
18
- $database.server_stop
19
-
20
- on_rollback lambda {
21
- $database.server_start
22
- }
23
-
24
- # Remove the symbolic link
25
- exec_unlink "#{mysql_data_dir}/#{$options[:database]}", mount_dir
26
-
27
- # Unmount the logical volume
28
- exec_unmount "/dev/#{volume_group_name}/#{logical_volume_name}", mount_dir
29
-
30
- # Deactivate the logical volume
31
- exec_deactivate "/dev/#{volume_group_name}/#{logical_volume_name}"
32
-
33
- # Merge the old logical volume into the new one
34
- # lvconvert --merge /dev/{vgName}/backup-{dbName}
35
- run "Merging the snapshot into the live logical volume",
36
- "lvconvert --merge /dev/#{volume_group_name}/#{$config['lvm']['prefix_backup']}-#{$options[:database]}"
37
-
38
- # Active the master drive
39
- # lvchange -ay /dev/{vgName}/mysql-{dbName}
40
- exec_activate "/dev/#{volume_group_name}/#{logical_volume_name}"
41
-
42
- # Mount the logical volume
43
- exec_mount "/dev/#{volume_group_name}/#{logical_volume_name}", mount_dir
44
-
45
- # Symbolic-link the MySQL data directory to the new logical volume
46
- exec_link "#{mysql_data_dir}/#{$options[:database]}", mount_dir
47
-
48
- # Change the permissions & ownership to MySQL
49
- # chown -R mysql:mysql {mysql-data-dir}/{dbName}/
50
- # chown -R mysql:mysql /mnt/mysql/{dbName}/
51
- exec_chown "#{mysql_data_dir}/#{$options[:database]}"
52
- exec_chown "#{mount_dir}"
53
-
54
- # Start the MySQL Server
55
- $database.server_start
56
-
57
- on_rollback lambda {
58
- $database.server_stop
59
- }
60
- end
61
- end
62
- end
63
- end
@@ -1,74 +0,0 @@
1
- require "singleton"
2
-
3
- module Snapback
4
- module App
5
- class Snapshot
6
- include Singleton
7
-
8
- def go
9
- # Ensure we have a size parameter
10
- if $options[:size].nil? then
11
- raise "You must specify a size attribute. E.g.: -s 100M"
12
- end
13
-
14
- if !$database.db_exists?($options[:database]) then
15
- raise "Database '#{$options[:database]}' does not exist"
16
- end
17
-
18
- volume_group_name = "#{$config['lvm']['volume_group']}"
19
- logical_volume_name = "#{$config['lvm']['prefix_database']}-#{$options[:database]}"
20
- mount_dir = get_mount_dir $options[:database]
21
- mysql_data_dir = $database.get_data_dir
22
-
23
- # Flush the MySQL Logs
24
- exec_flush
25
-
26
- # Stop the MySQL Server
27
- $database.server_stop
28
-
29
- on_rollback lambda {
30
- $database.server_start
31
- }
32
-
33
- # Unlink
34
- exec_unlink "#{mysql_data_dir}/#{$options[:database]}", mount_dir
35
-
36
- # Unmount
37
- exec_unmount "/dev/#{volume_group_name}/#{logical_volume_name}", mount_dir
38
-
39
- # Deactivate
40
- exec_deactivate "/dev/#{volume_group_name}/#{logical_volume_name}"
41
-
42
- # Branch the logical volume with a snapshot
43
- run "Snapshot the logical volume",
44
- "lvcreate -L #{$options[:size]} -s -n #{$config['lvm']['prefix_backup']}-#{$options[:database]} /dev/#{volume_group_name}/#{logical_volume_name}"
45
-
46
- on_rollback lambda {
47
- run "Remove the snapshot",
48
- "lvremove /dev/#{volume_group_name}/#{$config['lvm']['prefix_backup']}-#{$options[:database]}"
49
- }
50
-
51
- # Active the master drive
52
- exec_activate "/dev/#{volume_group_name}/#{logical_volume_name}"
53
-
54
- # Mount the master drive
55
- exec_mount "/dev/#{volume_group_name}/#{logical_volume_name}", mount_dir
56
-
57
- # Symbolic-link the MySQL data directory to the new logical volume
58
- # ln -s /mnt/mysql/{dbName} {mysql-data-dir}/{dbName}/
59
- exec_link "#{mysql_data_dir}/#{$options[:database]}", mount_dir
60
-
61
- # Change the permissions & ownership to MySQL
62
- exec_chown "#{mysql_data_dir}/#{$options[:database]}"
63
- exec_chown mount_dir
64
-
65
- # Start the MySQL Server
66
- $database.server_start
67
-
68
- on_rollback lambda {
69
- $database.server_stop
70
- }
71
- end
72
- end
73
- end
74
- end
@@ -1,39 +0,0 @@
1
- require "singleton"
2
-
3
- module Snapback
4
- module App
5
- class Unmount
6
- include Singleton
7
-
8
- def go
9
- volume_group_name = "#{$config['lvm']['volume_group']}"
10
- logical_volume_name = "#{$config['lvm']['prefix_database']}-#{$options[:database]}"
11
- mount_dir = get_mount_dir $options[:database]
12
- mysql_data_dir = $database.get_data_dir
13
-
14
- # Flush
15
- exec_flush
16
-
17
- # Stop the MySQL Server
18
- $database.server_stop
19
-
20
- on_rollback lambda {
21
- $database.server_start
22
- }
23
-
24
- # Unlink
25
- exec_unlink "#{mysql_data_dir}/#{$options[:database]}", mount_dir
26
-
27
- # Unmount
28
- exec_unmount "/dev/#{volume_group_name}/#{logical_volume_name}", mount_dir
29
-
30
- # Start the MySQL Server
31
- $database.server_start
32
-
33
- on_rollback lambda {
34
- $database.server_stop
35
- }
36
- end
37
- end
38
- end
39
- end
@@ -1,102 +0,0 @@
1
- require 'singleton'
2
- require 'mysql'
3
-
4
- # ## Database functions ##
5
-
6
- module Snapback
7
- class Database
8
- include Singleton
9
-
10
- attr_accessor :hostname, :username, :password
11
-
12
- @connection = nil
13
-
14
- @hostname = ""
15
- @username = ""
16
- @password = ""
17
-
18
- def connect
19
- @connection = Mysql.new @hostname, @username, @password
20
- end
21
-
22
- def flush_lock
23
- begin
24
- @connection.query "FLUSH TABLES WITH READ LOCK"
25
- end
26
-
27
- true
28
- end
29
-
30
- def unlock
31
- begin
32
- @connection.query "UNLOCK TABLES"
33
- end
34
-
35
- true
36
- end
37
-
38
- def get_data_dir
39
- begin
40
- rs = @connection.query "SHOW VARIABLES LIKE 'datadir'"
41
- rs.each_hash do |row|
42
- return row['Value'].gsub(/\/$/, '')
43
- end
44
- end
45
- end
46
-
47
- def innodb_file_per_table
48
- begin
49
- rs = @connection.query "SHOW VARIABLES LIKE 'innodb_file_per_table'"
50
- rs.each_hash do |row|
51
- return row['Value'] == "ON"
52
- end
53
- rescue
54
- raise "MySQL Query failed"
55
- end
56
- end
57
-
58
- def set_innodb_file_per_table on
59
- begin
60
- rs = @connection.prepare "SET GLOBAL innodb_file_per_table = ?"
61
- rs.execute(on ? 'ON' : 'OFF')
62
- return true
63
- rescue
64
- raise "MySQL Query failed"
65
- end
66
- end
67
-
68
- def db_exists? database_name
69
- sql = @connection.list_dbs database_name
70
- sql.size == 1
71
- end
72
-
73
- def db_create database_name
74
- @connection.query "CREATE DATABASE `#{Mysql.escape_string database_name}`"
75
- true
76
- end
77
-
78
- def db_drop database_name
79
- @connection.query "DROP DATABASE `#{Mysql.escape_string database_name}`"
80
- true
81
- end
82
-
83
- def db_use database_name
84
- @connection.select_db database_name
85
- true
86
- end
87
-
88
- def server_stop
89
- run "Stop MySQL server",
90
- "service mysql stop"
91
- true
92
- end
93
-
94
- def server_start
95
- run "Start MySQL server and reconnect",
96
- "service mysql start"
97
-
98
- self.connect
99
- true
100
- end
101
- end
102
- end