rubber 2.0.0.pre9 → 2.0.0.pre10

Sign up to get free protection for your applications and to get access to all the features.
@@ -156,6 +156,9 @@ module Rubber
156
156
  option ["-d", "--directory"],
157
157
  "DIRECTORY",
158
158
  "The directory to stage backups into\nRequired"
159
+ option ["-f", "--filename"],
160
+ "FILENAME",
161
+ "The name of the backup file"
159
162
  option ["-u", "--dbuser"],
160
163
  "DBUSER",
161
164
  "The database user to connect with\nRequired"
@@ -177,9 +180,12 @@ module Rubber
177
180
  def execute
178
181
  signal_usage_error "DIRECTORY, DBUSER, DBHOST, DBNAME are required" unless directory && dbuser && dbhost && dbname
179
182
 
180
-
181
183
  time_stamp = Time.now.strftime("%Y-%m-%d_%H-%M")
182
- backup_file = "#{directory}/#{Rubber.env}_dump_#{time_stamp}.sql.gz"
184
+ if filename
185
+ backup_file = "#{directory}/#{filename}"
186
+ else
187
+ backup_file = "#{directory}/#{Rubber.env}_dump_#{time_stamp}.sql.gz"
188
+ end
183
189
  FileUtils.mkdir_p(File.dirname(backup_file))
184
190
 
185
191
  # extra variables for command interpolation
@@ -35,7 +35,7 @@ module Rubber
35
35
  end
36
36
 
37
37
  def find_or_create_zone(domain)
38
- zone = @client.zones.all.find {|z| z.domain =~ /#{domain}\.?/}
38
+ zone = @client.zones.all.find {|z| z.domain =~ /^#{domain}\.?/}
39
39
  if ! zone
40
40
  zone = @client.zones.create(:domain => domain)
41
41
  end
@@ -1,4 +1,4 @@
1
1
  module Rubber
2
- VERSION = "2.0.0.pre9"
2
+ VERSION = "2.0.0.pre10"
3
3
  end
4
4
 
@@ -38,6 +38,8 @@
38
38
  /{,var/}run/mysqld/mysqld.pid w,
39
39
  /{,var/}run/mysqld/mysqld.sock w,
40
40
 
41
+ /usr/lib/mysql/plugin/ r,
42
+
41
43
  /sys/devices/system/cpu/ r,
42
44
  /sys/devices/system/cpu/** r,
43
45
 
@@ -42,7 +42,7 @@ nice = 0
42
42
  #
43
43
  # * Basic Settings
44
44
  #
45
- default-character-set = utf8
45
+ character-set-server = utf8
46
46
  user = mysql
47
47
  pid-file = /var/run/mysqld/mysqld.pid
48
48
  socket = /var/run/mysqld/mysqld.sock
@@ -0,0 +1,12 @@
1
+ <%
2
+ @path = "#{Rubber.root}/config/database.yml"
3
+ %>
4
+
5
+ <%= Rubber.env %>:
6
+ adapter: <%= YAML::load(File.open("#{Rubber.root}/config/database.yml"))["production"]["adapter"] %>
7
+ encoding: utf8
8
+ database: <%= rubber_env.db_name %>
9
+ username: <%= rubber_env.db_user %>
10
+ password: <%= rubber_env.db_pass %>
11
+ host: <%= rubber_instances.for_role('db', 'primary' => true).first.full_name %>
12
+ pool: 5
@@ -0,0 +1,169 @@
1
+ namespace :rubber do
2
+
3
+ namespace :percona do
4
+
5
+ rubber.allow_optional_tasks(self)
6
+
7
+ before "rubber:install_packages", "rubber:percona:add_repo"
8
+
9
+ task :add_repo, :roles => [:percona_master, :percona_slave] do
10
+ # Setup apt sources for percona
11
+ codename = capture('lsb_release -c -s').chomp
12
+ sources = <<-SOURCES
13
+ deb http://repo.percona.com/apt #{codename} main
14
+ deb-src http://repo.percona.com/apt #{codename} main
15
+ SOURCES
16
+ sources.gsub!(/^ */, '')
17
+ put(sources, "/etc/apt/sources.list.d/percona.list")
18
+ rsudo "gpg --keyserver hkp://keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A"
19
+ rsudo "gpg -a --export CD2EFD2A | apt-key add -"
20
+ end
21
+
22
+ after "rubber:create", "rubber:percona:validate_db_roles"
23
+
24
+ task :validate_db_roles do
25
+ db_instances = rubber_instances.for_role("percona_slave")
26
+ db_instances.each do |instance|
27
+ if instance.role_names.find {|n| n == 'percona_master'}
28
+ fatal "Cannot have a percona slave and master on the same instance, please removing slave role for #{instance.name}"
29
+ end
30
+ end
31
+ end
32
+
33
+ after "rubber:bootstrap", "rubber:percona:bootstrap"
34
+
35
+
36
+ # Bootstrap the production database config. Db bootstrap is special - the
37
+ # user could be requiring the rails env inside some of their config
38
+ # templates, which creates a catch 22 situation with the db, so we try and
39
+ # bootstrap the db separate from the rest of the config
40
+ task :bootstrap, :roles => [:percona_master, :percona_slave] do
41
+
42
+ # Conditionaly bootstrap for each node/role only if that node has not
43
+ # been boostrapped for that role before
44
+
45
+ master_instances = rubber_instances.for_role("percona_master") & rubber_instances.filtered
46
+ master_instances.each do |ic|
47
+ task_name = "_bootstrap_percona_master_#{ic.full_name}".to_sym()
48
+ task task_name, :hosts => ic.full_name do
49
+ env = rubber_cfg.environment.bind("percona_master", ic.name)
50
+ exists = capture("echo $(ls #{env.db_data_dir}/ 2> /dev/null)")
51
+ if exists.strip.size == 0
52
+ common_bootstrap("percona_master")
53
+
54
+ pass = "identified by '#{env.db_pass}'" if env.db_pass
55
+ rubber.sudo_script "create_master_db", <<-ENDSCRIPT
56
+ mysql -u root -e "create database #{env.db_name};"
57
+ mysql -u root -e "grant all on *.* to '#{env.db_user}'@'%' #{pass};"
58
+ mysql -u root -e "grant select on *.* to '#{env.db_slave_user}'@'%' #{pass};"
59
+ mysql -u root -e "grant replication slave on *.* to '#{env.db_replicator_user}'@'%' #{pass};"
60
+ mysql -u root -e "flush privileges;"
61
+ ENDSCRIPT
62
+ end
63
+ end
64
+ send task_name
65
+ end
66
+
67
+ slave_instances = rubber_instances.for_role("percona_slave") & rubber_instances.filtered
68
+ slave_instances.each do |ic|
69
+ task_name = "_bootstrap_percona_slave_#{ic.full_name}".to_sym()
70
+ task task_name, :hosts => ic.full_name do
71
+ env = rubber_cfg.environment.bind("percona_slave", ic.name)
72
+ exists = capture("echo $(ls #{env.db_data_dir}/ 2> /dev/null)")
73
+ if exists.strip.size == 0
74
+ common_bootstrap("percona_slave")
75
+
76
+ master = rubber_instances.for_role("percona_master").first
77
+
78
+ # Doing a mysqldump locks the db, so ideally we'd do it against a slave replica thats
79
+ # not serving traffic (mysql_util role), but if thats not available try a regular
80
+ # slave (percona_slave role), and finally default dumping from master (percona_master role)
81
+ # TODO: handle simultaneous creating of multi slaves/utils
82
+ slaves = rubber_instances.for_role("percona_slave")
83
+ slaves.delete(ic) # don't want to try and dump from self
84
+ source = slaves.find {|sc| sc.role_names.include?("mysql_util")}
85
+ source = slaves.first unless source
86
+ source = master unless source
87
+
88
+ pass = "identified by '#{env.db_pass}'" if env.db_pass
89
+ master_pass = ", master_password='#{env.db_pass}'" if env.db_pass
90
+ master_host = master.full_name
91
+ source_host = source.full_name
92
+
93
+ if source == master
94
+ logger.info "Creating slave from a dump of master #{source_host}"
95
+ rubber.sudo_script "create_slave_db_from_master", <<-ENDSCRIPT
96
+ mysql -u root -e "change master to master_host='#{master_host}', master_user='#{env.db_replicator_user}' #{master_pass}"
97
+ mysqldump -u #{env.db_user} #{env.db_pass.nil? ? '' : '--password=' + env.db_pass} -h #{source_host} --all-databases --master-data=1 | mysql -u root
98
+ ENDSCRIPT
99
+ else
100
+ logger.info "Creating slave from a dump of slave #{source_host}"
101
+ rsudo "mysql -u #{env.db_user} --password #{env.db_pass} -h #{source_host} -e \"stop slave;\""
102
+ slave_status = capture("mysql -u #{env.db_user} #{pass} -h #{source_host} -e \"show slave status\\G\"")
103
+ slave_config = Hash[*slave_status.scan(/([^\s:]+): ([^\s]*)/).flatten]
104
+ log_file = slave_config['Master_Log_File']
105
+ log_pos = slave_config['Read_Master_Log_Pos']
106
+ rubber.sudo_script "create_slave_db_from_slave", <<-ENDSCRIPT
107
+ mysqldump -u #{env.db_user} #{env.db_pass.nil? ? '' : '--password=' + env.db_pass} -h #{source_host} --all-databases --master-data=1 | mysql -u root
108
+ mysql -u root -e "change master to master_host='#{master_host}', master_user='#{env.db_replicator_user}', master_log_file='#{log_file}', master_log_pos=#{log_pos} #{master_pass}"
109
+ mysql -u #{env.db_user} --password #{env.db_pass} -h #{source_host} -e "start slave;"
110
+ ENDSCRIPT
111
+ end
112
+
113
+ # this doesn't work without agent forwarding which sudo breaks, as well as not having your
114
+ # ec2 private key ssh-added on workstation
115
+ # sudo "scp -o \"StrictHostKeyChecking=no\" #{source_host}:/etc/mysql/debian.cnf /etc/mysql"
116
+
117
+ rsudo "mysql -u root -e \"flush privileges;\""
118
+ rsudo "mysql -u root -e \"start slave;\""
119
+ end
120
+ end
121
+ send task_name
122
+ end
123
+
124
+ end
125
+
126
+ # TODO: Make the setup/update happen just once per host
127
+ def common_bootstrap(role)
128
+ # mysql package install starts mysql, so stop it
129
+ rsudo "service mysql stop" rescue nil
130
+
131
+ # After everything installed on machines, we need the source tree
132
+ # on hosts in order to run rubber:config for bootstrapping the db
133
+ rubber.update_code_for_bootstrap
134
+
135
+ # Gen just the conf for the given mysql role
136
+ rubber.run_config(:file => "role/#{role}|role/db/", :force => true, :deploy_path => release_path)
137
+
138
+ # reconfigure mysql so that it sets up data dir in /mnt with correct files
139
+ sudo_script 'reconfigure-mysql', <<-ENDSCRIPT
140
+ server_package=`dpkg -l | grep percona-server-server-[0-9] | awk '{print $2}'`
141
+ dpkg-reconfigure --frontend=noninteractive $server_package
142
+ ENDSCRIPT
143
+ sleep 5
144
+ end
145
+
146
+ desc <<-DESC
147
+ Starts the mysql daemons
148
+ DESC
149
+ task :start, :roles => [:percona_master, :percona_slave] do
150
+ rsudo "service mysql start"
151
+ end
152
+
153
+ desc <<-DESC
154
+ Stops the mysql daemons
155
+ DESC
156
+ task :stop, :roles => [:percona_master, :percona_slave] do
157
+ rsudo "service mysql stop"
158
+ end
159
+
160
+ desc <<-DESC
161
+ Restarts the mysql daemons
162
+ DESC
163
+ task :restart, :roles => [:percona_master, :percona_slave] do
164
+ rsudo "service mysql restart"
165
+ end
166
+
167
+ end
168
+
169
+ end
@@ -0,0 +1,49 @@
1
+ <%
2
+ @path = '/etc/apparmor.d/usr.sbin.mysqld'
3
+ @post = "service apparmor restart"
4
+ @backup = false
5
+ %>
6
+
7
+ #include <tunables/global>
8
+
9
+ /usr/sbin/mysqld {
10
+ #include <abstractions/base>
11
+ #include <abstractions/nameservice>
12
+ #include <abstractions/user-tmp>
13
+ #include <abstractions/mysql>
14
+ #include <abstractions/winbind>
15
+
16
+ capability dac_override,
17
+ capability sys_resource,
18
+ capability setgid,
19
+ capability setuid,
20
+
21
+ network tcp,
22
+
23
+ /etc/hosts.allow r,
24
+ /etc/hosts.deny r,
25
+
26
+ /etc/mysql/*.pem r,
27
+ /etc/mysql/conf.d/ r,
28
+ /etc/mysql/conf.d/* r,
29
+ /etc/mysql/my.cnf r,
30
+ /usr/sbin/mysqld mr,
31
+ /usr/share/mysql/** r,
32
+ /var/log/mysql.log rw,
33
+ /var/log/mysql.err rw,
34
+ /var/lib/mysql/ r,
35
+ /var/lib/mysql/** rwk,
36
+ /var/log/mysql/ r,
37
+ /var/log/mysql/* rw,
38
+ /{,var/}run/mysqld/mysqld.pid w,
39
+ /{,var/}run/mysqld/mysqld.sock w,
40
+
41
+ /etc/mtab r,
42
+ /usr/lib/mysql/plugin/ r,
43
+
44
+ /sys/devices/system/cpu/ r,
45
+ /sys/devices/system/cpu/** r,
46
+
47
+ <%= rubber_env.db_root_dir %>/ r,
48
+ <%= rubber_env.db_root_dir %>/** rwk,
49
+ }
@@ -0,0 +1,16 @@
1
+ <%
2
+ @read_cmd = 'crontab -l'
3
+ @write_cmd = 'crontab -'
4
+ @additive = ["# rubber-mysql-start", "# rubber-mysql-end"]
5
+ %>
6
+
7
+ <%
8
+ # Backup db every 3 hours to secondary db if available, else primary db
9
+ backup_db_host = rubber_instances.for_role('db', {}).first rescue nil
10
+ backup_db_host ||= rubber_instances.for_role('db', 'primary' => true).first
11
+ if backup_db_host.name == rubber_env.host
12
+ %>
13
+
14
+ 0 */3 * * * <%= Rubber.root %>/script/rubber cron --task util:backup_db --directory=/mnt/db_backups --dbuser=<%= rubber_env.db_user %> --dbpass=<%= rubber_env.db_pass %> --dbname=<%= rubber_env.db_name %> --dbhost=<%= backup_db_host.full_name %>
15
+
16
+ <% end %>
@@ -0,0 +1,163 @@
1
+ <%
2
+ data_dir = rubber_env.db_data_dir
3
+ log_dir = rubber_env.db_log_dir
4
+ server_id = rubber_env.db_server_id
5
+ @path = '/etc/mysql/my.cnf'
6
+ @post = "mkdir -p #{log_dir}; chown mysql:adm #{log_dir}; chmod 2750 #{log_dir}"
7
+ %>
8
+
9
+ # Generated by rubber for host <%= rubber_instances[rubber_env.host].external_ip %>
10
+ #
11
+ # The MySQL database server configuration file.
12
+ #
13
+ # You can copy this to one of:
14
+ # - "/etc/mysql/my.cnf" to set global options,
15
+ # - "~/.my.cnf" to set user-specific options.
16
+ #
17
+ # One can use all long options that the program supports.
18
+ # Run program with --help to get a list of available options and with
19
+ # --print-defaults to see which it would actually understand and use.
20
+ #
21
+ # For explanations see
22
+ # http://dev.mysql.com/doc/mysql/en/server-system-variables.html
23
+
24
+ # This will be passed to all mysql clients
25
+ # It has been reported that passwords should be enclosed with ticks/quotes
26
+ # escpecially if they contain "#" chars...
27
+ # Remember to edit /etc/mysql/debian.cnf when changing the socket location.
28
+ [client]
29
+ default-character-set = utf8
30
+ port = 3306
31
+ socket = /var/run/mysqld/mysqld.sock
32
+
33
+ # Here is entries for some specific programs
34
+ # The following values assume you have at least 32M ram
35
+
36
+ # This was formally known as [safe_mysqld]. Both versions are currently parsed.
37
+ [mysqld_safe]
38
+ socket = /var/run/mysqld/mysqld.sock
39
+ nice = 0
40
+
41
+ [mysqld]
42
+ #
43
+ # * Basic Settings
44
+ #
45
+ character-set-server = utf8
46
+ user = mysql
47
+ pid-file = /var/run/mysqld/mysqld.pid
48
+ socket = /var/run/mysqld/mysqld.sock
49
+ port = 3306
50
+ basedir = /usr
51
+ datadir = <%= data_dir %>
52
+ tmpdir = /tmp
53
+ language = /usr/share/mysql/english
54
+ skip-external-locking
55
+
56
+ #
57
+ # Instead of skip-networking the default is now to listen only on
58
+ # localhost which is more compatible and is not less secure.
59
+ # bind-address = 127.0.0.1
60
+ #
61
+ # * Fine Tuning
62
+ #
63
+ key_buffer = 16M
64
+ max_allowed_packet = 32M
65
+ thread_stack = 128K
66
+ thread_cache_size = 8
67
+ #table_cache=500
68
+ #max_heap_table_size=16M
69
+ #tmp_table_size=32M
70
+
71
+ #max_connections = 100
72
+ #table_cache = 64
73
+ #thread_concurrency = 10
74
+ #
75
+ # * Query Cache Configuration
76
+ #
77
+ query_cache_limit = 1M
78
+ query_cache_size = 16M
79
+ #
80
+ # * Logging and Replication
81
+ #
82
+ # Both location gets rotated by the cronjob.
83
+ # Be aware that this log type is a performance killer.
84
+ #log = /var/log/mysql/mysql.log
85
+ #
86
+ # Error logging goes to syslog. This is a Debian improvement :)
87
+ #
88
+ # Here you can see queries with especially long duration
89
+ log_slow_queries = /var/log/mysql/mysql-slow.log
90
+ long_query_time = 2
91
+ log-queries-not-using-indexes
92
+ #
93
+ # The following can be used as easy to replay backup logs or for replication.
94
+ # note: if you are setting up a replication slave, see README.Debian about
95
+ # other settings you may need to change.
96
+ server-id = <%= server_id %>
97
+ log_bin = <%= log_dir %>/mysql-bin.log
98
+ relay_log = <%= log_dir %>/mysql-relay-bin.log
99
+
100
+ # WARNING: Using expire_logs_days without bin_log crashes the server! See README.Debian!
101
+ expire_logs_days = 10
102
+ max_binlog_size = 100M
103
+ #binlog_do_db = include_database_name
104
+ #binlog_ignore_db = include_database_name
105
+
106
+
107
+ # * InnoDB
108
+ #
109
+ # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
110
+ # Read the manual for more InnoDB related options. There are many!
111
+ # You might want to disable InnoDB to shrink the mysqld process by circa 100MB.
112
+ #skip-innodb
113
+
114
+ # Set buffer pool size to 50-80% of your computer's memory
115
+ #innodb_buffer_pool_size=512M
116
+ #innodb_additional_mem_pool_size=64M
117
+
118
+ # Set the log file size to about 25% of the buffer pool size
119
+ #innodb_log_file_size=128M
120
+ #innodb_log_buffer_size=32M
121
+ #innodb_flush_log_at_trx_commit=2
122
+
123
+ #
124
+ # * Security Features
125
+ #
126
+ # Read the manual, too, if you want chroot!
127
+ # chroot = /var/lib/mysql/
128
+ #
129
+ # For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
130
+ #
131
+ # ssl-ca=/etc/mysql/cacert.pem
132
+ # ssl-cert=/etc/mysql/server-cert.pem
133
+ # ssl-key=/etc/mysql/server-key.pem
134
+
135
+
136
+
137
+ [mysqldump]
138
+ quick
139
+ quote-names
140
+ max_allowed_packet = 16M
141
+
142
+ [mysql]
143
+ #no-auto-rehash # faster start of mysql but no tab completition
144
+
145
+ [isamchk]
146
+ key_buffer = 16M
147
+
148
+ #
149
+ # * NDB Cluster
150
+ #
151
+ # See /usr/share/doc/mysql-server-*/README.Debian for more information.
152
+ #
153
+ # The following configuration is read by the NDB Data Nodes (ndbd processes)
154
+ # not from the NDB Management Nodes (ndb_mgmd processes).
155
+ #
156
+ # [MYSQL_CLUSTER]
157
+ # ndb-connectstring=127.0.0.1
158
+
159
+
160
+ #
161
+ # * IMPORTANT: Additional settings that can override those from this file!
162
+ #
163
+ !includedir /etc/mysql/conf.d/
@@ -0,0 +1,43 @@
1
+ # REQUIRED: The credentials for creating/accessong your app's database
2
+ #
3
+ db_user: "#{app_name[0,16]}"
4
+ db_pass:
5
+ db_name: "#{app_name}_#{Rubber.env}"
6
+
7
+ db_slave_user: "#{('slave_' + db_user)[0,16]}"
8
+ db_replicator_user: "#{('replicator_' + db_user)[0,16]}"
9
+
10
+ # REQUIRED: The command to use to do a full backup of your database using
11
+ # "rubber util:backup_db"
12
+ db_backup_cmd: "nice mysqldump -h %host% -u %user% --password=%pass% %name% | gzip -c > %backup_file%"
13
+ # REQUIRED: The command to use to restore the database using
14
+ # "rubber util:restore_db_s3"
15
+ # This command will receive the data generated by db_backup_cmd via
16
+ # its standard input
17
+ db_restore_cmd: "zcat - | mysql -h %host% -u %user% --password=%pass% %name%"
18
+
19
+ # REQUIRED: The directory to store the db data in
20
+ #
21
+ db_root_dir: /mnt/mysql
22
+ db_data_dir: "#{db_root_dir}/data"
23
+ db_log_dir: "#{db_root_dir}/log"
24
+
25
+ role_dependencies:
26
+ percona_master: [percona, "db:primary=true"]
27
+ percona_slave: [percona, db]
28
+ db:primary=true: [percona, percona_master]
29
+ db: [percona, percona_slave]
30
+
31
+ packages: [percona-server-client, libmysqlclient-dev]
32
+ gems: [mysql]
33
+
34
+ roles:
35
+ percona_master:
36
+ db_server_id: 1
37
+ percona_slave:
38
+ db_server_id: 2
39
+ percona:
40
+ packages: [
41
+ percona-server-server,
42
+ maatkit # useful mysql tools for replication
43
+ ]
@@ -0,0 +1 @@
1
+ description: The percona mysql server module
@@ -0,0 +1,24 @@
1
+ namespace :rubber do
2
+
3
+ namespace :xtrabackup do
4
+
5
+ rubber.allow_optional_tasks(self)
6
+
7
+ before "rubber:install_packages", "rubber:xtrabackup:add_repo"
8
+
9
+ task :add_repo, :roles => [:percona, :mysql] do
10
+ # Setup apt sources for percona
11
+ codename = capture('lsb_release -c -s').chomp
12
+ sources = <<-SOURCES
13
+ deb http://repo.percona.com/apt #{codename} main
14
+ deb-src http://repo.percona.com/apt #{codename} main
15
+ SOURCES
16
+ sources.gsub!(/^ */, '')
17
+ put(sources, "/etc/apt/sources.list.d/percona.list")
18
+ rsudo "gpg --keyserver hkp://keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A"
19
+ rsudo "gpg -a --export CD2EFD2A | apt-key add -"
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,246 @@
1
+ <%
2
+ @path = "/mnt/db-backup-tools/rubber-xtrabackup.sh"
3
+ @perms = 0755
4
+ @backup = false
5
+ %>#!/bin/bash
6
+ #
7
+ # Run innobackupex for databases, ensure it succeeded, and put file in place for S3 upload by Rubber.
8
+ # First, set up some variables.
9
+ INNOBACKUP="/usr/bin/innobackupex"
10
+ LOGFILE="/tmp/rubber-xtrabackup-log"
11
+ MEMORY="512M"
12
+ MYSQL="/usr/bin/mysql"
13
+ MYSQLADMIN="/usr/bin/mysqladmin"
14
+ # If you use MyISAM tables, comment this out or Bad Things will happen. Leave as-is if you use InnoDB.
15
+ NOLOCK="--no-lock"
16
+ # By default, don't use differential backups unless -d command line argument supplied.
17
+ DIFFERENTIALS=0
18
+ # The number of differential backups to perform before rotating into a new full backup
19
+ # NOTE: Ensure you have enough disk space to keep this amount of diffs on the volume
20
+ # you supply via the -t (backup directory) option.
21
+ MAXDIFFS=24
22
+ # Some folks have empty passwords and won't supply one.
23
+ PASSWORD=""
24
+ # Have rubber include slave commands if we're on a slave.
25
+ <% dbm_inst = rubber_instances.for_role('db', 'primary' => true).collect { |i| i.name }
26
+ if dbm_inst.include?(rubber_env.host)
27
+ %>
28
+ # We're on a primary DB instance
29
+ SLAVECMD=""
30
+ <% else %>
31
+ # We're on a slave DB instance.
32
+ SLAVECMD="--safe-slave-backup --slave-info"
33
+ <% end %>
34
+
35
+ # Lets get our command line parameters
36
+ while getopts ":u:p:t:db:" opt; do
37
+ case $opt in
38
+ u)
39
+ USERNAME="$OPTARG"
40
+ ;;
41
+ p)
42
+ PASSWORD="$OPTARG"
43
+ ;;
44
+ t)
45
+ BACKUPDIR="$OPTARG"
46
+ ;;
47
+ b)
48
+ BACKUPFILE="$OPTARG"
49
+ ;;
50
+ d)
51
+ DIFFERENTIALS=1
52
+ ;;
53
+ \?)
54
+ echo "Invalid option: -$OPTARG" >&2
55
+ exit 1
56
+ ;;
57
+ :)
58
+ echo "Option -$OPTARG requires an argument." >&2
59
+ exit 1
60
+ ;;
61
+ esac
62
+ done
63
+
64
+ if [[ -z "$USERNAME" || -z "$BACKUPDIR" || -z "$BACKUPFILE" ]]; then
65
+ echo "Required parameters missing. Please supply -u (database username), -t (backup directory) and -b (backup file)"
66
+ exit 1
67
+ fi
68
+
69
+ differential_backup () {
70
+ # This method will handle differential backups
71
+ BASEDIR="$BACKUPDIR/diffs/base"
72
+
73
+ if [ ! -d "$BASEDIR" ]; then
74
+ echo "$BASEDIR does not exist. Running full base backup..."
75
+ clean_base_backup
76
+ echo "Success. Exiting."
77
+ exit 0
78
+ else
79
+ if [ -f "$BACKUPDIR/diffs/diff-status" ]; then
80
+ # Check current diff number
81
+ DIFFNUM=`cat $BACKUPDIR/diffs/diff-status`
82
+ # Increase diff number by one
83
+ let "NEWDIFFNUM = $DIFFNUM + 1"
84
+ if [ "$NEWDIFFNUM" -gt "$MAXDIFFS" ]; then
85
+ echo "Exceeded maximum number of differentials. Performing new base backup."
86
+ clean_base_backup
87
+ echo "Success. Exiting."
88
+ exit 0
89
+ else
90
+ if [ "$NEWDIFFNUM" -eq "1" ]; then
91
+ # First diff, let's set the base for the diff to $BASEDIR
92
+ DIFFBASE=$BASEDIR
93
+ else
94
+ DIFFBASE="$BACKUPDIR/diffs/$DIFFNUM"
95
+ fi
96
+ # Run the backup
97
+ incremental_backup $DIFFBASE "$BACKUPDIR/diffs/$NEWDIFFNUM"
98
+ # Once this is verified we'll merge this incremental into the base folder
99
+ prepare_backup $BASEDIR "$BACKUPDIR/diffs/$NEWDIFFNUM"
100
+ # Then prepare the backup once again
101
+ prepare_backup $BASEDIR
102
+ # Finally, tar it all up.
103
+ tar czf $BACKUPFILE -C $BASEDIR .
104
+ # Update our diff status.
105
+ echo $NEWDIFFNUM > "$BACKUPDIR/diffs/diff-status"
106
+ echo "Success. exiting."
107
+ exit 0
108
+ fi
109
+ else
110
+ echo "Can't get backup status. Performing new base backup."
111
+ clean_base_backup
112
+ echo "Success. Exiting."
113
+ exit 0
114
+ fi
115
+ fi
116
+ }
117
+
118
+ full_backup () {
119
+ # This method will handle full backups for further processing.
120
+ # This function requires a single argument, the destination folder of the backup.
121
+ if [ -z "$1" ]; then
122
+ echo "ERROR: full_backup() called without destination parameter. Exiting."
123
+ exit 1
124
+ fi
125
+ echo "Running full backup into $1"
126
+ $INNOBACKUP --no-timestamp --user=$USERNAME $PASSCMD $SLAVECMD $NOLOCK $1 2> $LOGFILE
127
+ echo "Checking backup result..."
128
+ check_backup_result
129
+ }
130
+
131
+ prepare_backup () {
132
+ # This prepares the backups for immediate restore.
133
+ # This function supports two arguments:
134
+ # 1) The base folder (required)
135
+ # 2) The incremental folder (optional)
136
+ if [ -z "$1" ]; then
137
+ echo "ERROR: prepare_backup() called without base folder. Exiting."
138
+ exit 1
139
+ fi
140
+ if [ -z "$2" ]; then
141
+ $INNOBACKUP --apply-log --redo-only $1 2> $LOGFILE
142
+ else
143
+ $INNOBACKUP --apply-log --redo-only $1 --incremental-dir=$2 2> $LOGFILE
144
+ fi
145
+ check_backup_result
146
+ }
147
+
148
+ clean_base_backup () {
149
+ echo "Removing $BACKUPDIR/diffs to ensure clean start..."
150
+ rm -rf "$BACKUPDIR/diffs"
151
+ mkdir -p "$BACKUPDIR/diffs"
152
+ ensure_destination_exists
153
+ full_backup $BASEDIR
154
+ prepare_backup $BASEDIR
155
+ echo "Backup OK. Compressing backup..."
156
+ tar czf $BACKUPFILE -C $BASEDIR .
157
+ echo "Creating backup-status"
158
+ echo 0 > "$BACKUPDIR/diffs/diff-status"
159
+ }
160
+
161
+ incremental_backup () {
162
+ # This function requires two arguments:
163
+ # 1) The base folder for the incremental
164
+ # 2) The destination folder for the incremental
165
+ if [[ -z "$1" || -z "$2" ]]; then
166
+ echo "ERROR: incremental_backup() called without base or destination parameter. Exiting."
167
+ exit 1
168
+ fi
169
+ echo "Running incremental backup with base at $1 into $2"
170
+ $INNOBACKUP --no-timestamp --user=$USERNAME $PASSCMD $SLAVECMD $NOLOCK --incremental $2 --incremental-basedir=$1 2> $LOGFILE
171
+ echo "Checking backup result..."
172
+ check_backup_result
173
+ }
174
+
175
+ full_compressed_backup () {
176
+ # This method will create a full backup and compress it into $BACKUPFILE in one step.
177
+ # First remove the existing full backup, if any.
178
+ rm -rf "$BACKUPDIR/full"
179
+ ensure_destination_exists
180
+ full_backup "$BACKUPDIR/full"
181
+ echo "Checking backup result..."
182
+ check_backup_result
183
+ echo "Backup OK. Compressing backup..."
184
+ tar czf $BACKUPFILE -C "$BACKUPDIR/full" .
185
+ echo "Cleaning up"
186
+ rm -rf "$BACKUPDIR/full"
187
+ }
188
+
189
+ check_backup_result () {
190
+ if [ -z "`tail -1 $LOGFILE | grep 'completed OK!'`" ] ; then
191
+ echo "ERROR: $INNOBACKUPEX failed:"
192
+ echo "----------------------------"
193
+ cat $LOGFILE
194
+ rm -f $LOGFILE
195
+ rm -f $BACKUPFILE
196
+ exit 1
197
+ fi
198
+ }
199
+
200
+ ensure_destination_exists () {
201
+ mkdir -p `dirname $BACKUPFILE`
202
+ }
203
+
204
+ echo "----------------------------------"
205
+ echo "Started innobackupex backup script"
206
+ echo "Start: `date`"
207
+ echo "----------------------------------"
208
+
209
+ if [ ! -x "$INNOBACKUP" ]; then
210
+ echo "$INNOBACKUP does not exist. Ensure you have bootstrapped this instance and that the xtrabackup package is installed."
211
+ exit 1
212
+ fi
213
+
214
+ # Only supply --password if password supplied.
215
+ if [ -z "$PASSWORD" ]; then
216
+ PASSCMD=""
217
+ else
218
+ PASSCMD="--password=$PASSWORD"
219
+ fi
220
+
221
+ if [ -z "`$MYSQLADMIN --user=$USERNAME $PASSCMD status | grep 'Uptime'`" ] ; then
222
+ echo "ERROR: MySQL not running."
223
+ exit 1
224
+ fi
225
+
226
+ if ! `echo 'exit' | $MYSQL -s --user=$USERNAME $PASSCMD` ; then
227
+ echo "ERROR: Mysql username or password is incorrect"
228
+ exit 1
229
+ fi
230
+
231
+ if [ ! -d "$BACKUPDIR" ]; then
232
+ echo "$BACKUPDIR did not exist. Creating..."
233
+ mkdir -p $BACKUPDIR
234
+ fi
235
+
236
+ if [ "$DIFFERENTIALS" -eq "1" ]; then
237
+ echo "Running differential backup..."
238
+ differential_backup
239
+ echo "Success. Exiting."
240
+ exit 0
241
+ else
242
+ echo "Running full compressed backup..."
243
+ full_compressed_backup
244
+ echo "Success. Exiting."
245
+ exit 0
246
+ fi
@@ -0,0 +1,45 @@
1
+ <%
2
+ @path = "/mnt/db-backup-tools/rubber-xtrarestore.sh"
3
+ @perms = 0755
4
+ @backup = false
5
+ %>#!/bin/bash
6
+ # Variables
7
+ LOGFILE="/tmp/rubber-xtrarestore-log"
8
+ # Take the file from STDIN, write it into a real file, extract it, service mysql stop,
9
+ # then mkdir /mnt/mysql/data & /mnt/mysql/log (move old ones out of the way)
10
+ # then innobackupex --copy-back . in the extracted folder, then service mysql start
11
+ # Create a temporary folder
12
+ rm -rf /mnt/db_restore
13
+ mkdir -p /mnt/db_restore
14
+ # Write STDIN into file
15
+ cat > /mnt/db_restore/current.tar.gz
16
+ cd /mnt/db_restore
17
+ tar xzvf current.tar.gz
18
+ echo 'Stopping MySQL'
19
+ if [ -z "`service mysql stop | grep 'done'`" ] ; then
20
+ echo "ERROR: Couldn't stop mysql daemon."
21
+ exit 1
22
+ fi
23
+ rm -rf /mnt/mysql/old
24
+ mkdir -p /mnt/mysql/old
25
+ echo 'Moving Data/Log Directories to /old'
26
+ mv /mnt/mysql/data /mnt/mysql/log /mnt/mysql/old
27
+ mkdir /mnt/mysql/data /mnt/mysql/log
28
+ echo 'Copying back'
29
+ innobackupex --copy-back . 2> $LOGFILE
30
+ if [ -z "`tail -1 $LOGFILE | grep 'completed OK!'`" ] ; then
31
+ echo "ERROR: Innobackupex couldn't copy back."
32
+ exit 1
33
+ fi
34
+ chown -R mysql.mysql /mnt/mysql/data
35
+ chown -R mysql.mysql /mnt/mysql/log
36
+ echo 'Starting MySQL'
37
+ if [ -z "`service mysql start | grep 'done'`" ] ; then
38
+ echo "ERROR: Couldn't start mysql daemon."
39
+ exit 1
40
+ fi
41
+ echo 'Cleaning up'
42
+ rm -rf /mnt/mysql/old
43
+ rm -rf /mnt/db_restore
44
+ echo "Success."
45
+ exit 0
@@ -0,0 +1,6 @@
1
+ role_dependencies:
2
+ mysql: [xtrabackup]
3
+ percona: [xtrabackup]
4
+ roles:
5
+ xtrabackup:
6
+ packages: [xtrabackup]
@@ -0,0 +1,17 @@
1
+ if FileTest.exist?("config/rubber/rubber-percona.yml")
2
+ gsub_file "config/rubber/rubber-percona.yml", /^db_backup_cmd.*$/, \
3
+ "# Replaced by xtrabackup vulcanizer.\n# \\0\n" + \
4
+ "# ** If you'd like to run differential backups, add '-d' to the command line below.\n" + \
5
+ "db_backup_cmd: \"/mnt/db-backup-tools/rubber-xtrabackup.sh -u %user% -p %pass% -t /mnt/db_backups -b %backup_file%\"\n"
6
+ gsub_file "config/rubber/rubber-percona.yml", /^db_restore_cmd.*$/, \
7
+ "# Replaced by xtrabackup vulcanizer.\n# \\0\n" + \
8
+ "db_restore_cmd: \"/mnt/db-backup-tools/rubber-xtrarestore.sh\"\n"
9
+ elsif FileTest.exist?("config/rubber/rubber-mysql.yml")
10
+ gsub_file "config/rubber/rubber-mysql.yml", /^db_backup_cmd.*$/, \
11
+ "# Replaced by xtrabackup vulcanizer.\n# \\0\n" + \
12
+ "# ** If you'd like to run differential backups, add '-d' to the command line below.\n" + \
13
+ "db_backup_cmd: \"/mnt/db-backup-tools/rubber-xtrabackup.sh -u %user% -p %pass% -t /mnt/db_backups -b %backup_file%\"\n"
14
+ gsub_file "config/rubber/rubber-mysql.yml", /^db_restore_cmd.*$/, \
15
+ "# Replaced by xtrabackup vulcanizer.\n# \\0\n" + \
16
+ "db_restore_cmd: \"/mnt/db-backup-tools/rubber-xtrarestore.sh\"\n"
17
+ end
@@ -0,0 +1 @@
1
+ description: "The xtrabackup module for MySQL/Percona Servers. When vulcanized, this module will replace itself as the Rubber database backup method. After vulcanization, simply run cap rubber:bootstrap (you can filter for DB roles if you like) and cap deploy."
data/test/dns/fog_test.rb CHANGED
@@ -34,12 +34,28 @@ class FogTest < Test::Unit::TestCase
34
34
  zone0 = @dns.find_or_create_zone("example1.com")
35
35
 
36
36
  assert_equal 1, @dns.client.zones.all.size
37
- zone1 = @dns.client.zones.all.find {|z| z.domain =~ /example1.com/ }
37
+ zone1 = @dns.client.zones.all.find {|z| z.domain =~ /^example1.com/ }
38
38
  assert zone1
39
39
  assert_equal zone0.id, zone1.id
40
40
  assert_equal zone0.domain, zone1.domain
41
41
  end
42
42
 
43
+ should "match the same domain that was passed" do
44
+ @dns = Rubber::Dns::Fog.new(@env)
45
+
46
+ assert_equal 0, @dns.client.zones.all.size
47
+
48
+ zone0 = @dns.find_or_create_zone("abcfoo.com")
49
+ zone1 = @dns.find_or_create_zone("foo.com")
50
+
51
+ assert_equal 2, @dns.client.zones.all.size
52
+
53
+ zone2 = @dns.client.zones.all.find {|z| z.domain =~ /^foo.com/ }
54
+ assert zone2
55
+ assert_equal zone1.id, zone2.id
56
+ assert_equal zone1.domain, zone2.domain
57
+ end
58
+
43
59
  should "do nothing if domain already exists" do
44
60
  @dns = Rubber::Dns::Fog.new(@env)
45
61
 
@@ -49,7 +65,7 @@ class FogTest < Test::Unit::TestCase
49
65
  zone0 = @dns.find_or_create_zone("example1.com")
50
66
 
51
67
  assert_equal 1, @dns.client.zones.all.size
52
- zone1 = @dns.client.zones.all.find {|z| z.domain =~ /example1.com/ }
68
+ zone1 = @dns.client.zones.all.find {|z| z.domain =~ /^example1.com/ }
53
69
  assert_equal zone0.id, zone1.id
54
70
  assert_equal zone0.domain, zone1.domain
55
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre9
4
+ version: 2.0.0.pre10
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-27 00:00:00.000000000 Z
13
+ date: 2012-04-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: capistrano
17
- requirement: &70315019511180 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: '2.8'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70315019511180
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '2.8'
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: thor
28
- requirement: &70315019491420 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ! '>='
@@ -33,10 +38,15 @@ dependencies:
33
38
  version: '0'
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: *70315019491420
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: clamp
39
- requirement: &70315019486920 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
40
50
  none: false
41
51
  requirements:
42
52
  - - ! '>='
@@ -44,10 +54,15 @@ dependencies:
44
54
  version: '0'
45
55
  type: :runtime
46
56
  prerelease: false
47
- version_requirements: *70315019486920
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
48
63
  - !ruby/object:Gem::Dependency
49
64
  name: open4
50
- requirement: &70315019481600 !ruby/object:Gem::Requirement
65
+ requirement: !ruby/object:Gem::Requirement
51
66
  none: false
52
67
  requirements:
53
68
  - - ! '>='
@@ -55,10 +70,15 @@ dependencies:
55
70
  version: '0'
56
71
  type: :runtime
57
72
  prerelease: false
58
- version_requirements: *70315019481600
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
59
79
  - !ruby/object:Gem::Dependency
60
80
  name: fog
61
- requirement: &70315019450520 !ruby/object:Gem::Requirement
81
+ requirement: !ruby/object:Gem::Requirement
62
82
  none: false
63
83
  requirements:
64
84
  - - ~>
@@ -66,10 +86,15 @@ dependencies:
66
86
  version: '1.2'
67
87
  type: :runtime
68
88
  prerelease: false
69
- version_requirements: *70315019450520
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: '1.2'
70
95
  - !ruby/object:Gem::Dependency
71
96
  name: rake
72
- requirement: &70315019443320 !ruby/object:Gem::Requirement
97
+ requirement: !ruby/object:Gem::Requirement
73
98
  none: false
74
99
  requirements:
75
100
  - - ! '>='
@@ -77,10 +102,15 @@ dependencies:
77
102
  version: '0'
78
103
  type: :development
79
104
  prerelease: false
80
- version_requirements: *70315019443320
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
81
111
  - !ruby/object:Gem::Dependency
82
112
  name: test-unit
83
- requirement: &70315019434780 !ruby/object:Gem::Requirement
113
+ requirement: !ruby/object:Gem::Requirement
84
114
  none: false
85
115
  requirements:
86
116
  - - ! '>='
@@ -88,10 +118,15 @@ dependencies:
88
118
  version: '0'
89
119
  type: :development
90
120
  prerelease: false
91
- version_requirements: *70315019434780
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
92
127
  - !ruby/object:Gem::Dependency
93
128
  name: shoulda-context
94
- requirement: &70315019432700 !ruby/object:Gem::Requirement
129
+ requirement: !ruby/object:Gem::Requirement
95
130
  none: false
96
131
  requirements:
97
132
  - - ! '>='
@@ -99,10 +134,15 @@ dependencies:
99
134
  version: '0'
100
135
  type: :development
101
136
  prerelease: false
102
- version_requirements: *70315019432700
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
103
143
  - !ruby/object:Gem::Dependency
104
144
  name: mocha
105
- requirement: &70315019431720 !ruby/object:Gem::Requirement
145
+ requirement: !ruby/object:Gem::Requirement
106
146
  none: false
107
147
  requirements:
108
148
  - - ! '>='
@@ -110,10 +150,15 @@ dependencies:
110
150
  version: '0'
111
151
  type: :development
112
152
  prerelease: false
113
- version_requirements: *70315019431720
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
114
159
  - !ruby/object:Gem::Dependency
115
160
  name: ruby-debug19
116
- requirement: &70315019428140 !ruby/object:Gem::Requirement
161
+ requirement: !ruby/object:Gem::Requirement
117
162
  none: false
118
163
  requirements:
119
164
  - - ! '>='
@@ -121,7 +166,12 @@ dependencies:
121
166
  version: '0'
122
167
  type: :development
123
168
  prerelease: false
124
- version_requirements: *70315019428140
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ! '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
125
175
  description: ! " The rubber plugin enables relatively complex multi-instance deployments
126
176
  of RubyOnRails applications to\n Amazon's Elastic Compute Cloud (EC2). Like
127
177
  capistrano, rubber is role based, so you can define a set\n of configuration
@@ -421,6 +471,13 @@ files:
421
471
  - templates/passenger_nginx/config/rubber/role/web_tools/tools-nginx.auth
422
472
  - templates/passenger_nginx/config/rubber/rubber-passenger_nginx.yml
423
473
  - templates/passenger_nginx/templates.yml
474
+ - templates/percona/config/rubber/common/database.yml
475
+ - templates/percona/config/rubber/deploy-percona.rb
476
+ - templates/percona/config/rubber/role/db/apparmor-mysql.conf
477
+ - templates/percona/config/rubber/role/db/crontab
478
+ - templates/percona/config/rubber/role/db/my.cnf
479
+ - templates/percona/config/rubber/rubber-percona.yml
480
+ - templates/percona/templates.yml
424
481
  - templates/postgresql/config/rubber/common/database.yml
425
482
  - templates/postgresql/config/rubber/deploy-postgresql.rb
426
483
  - templates/postgresql/config/rubber/role/db/crontab
@@ -458,6 +515,12 @@ files:
458
515
  - templates/unicorn/config/rubber/role/unicorn/unicorn.rb
459
516
  - templates/unicorn/config/rubber/rubber-unicorn.yml
460
517
  - templates/unicorn/templates.yml
518
+ - templates/xtrabackup/config/rubber/deploy-xtrabackup.rb
519
+ - templates/xtrabackup/config/rubber/role/db/rubber-xtrabackup.sh
520
+ - templates/xtrabackup/config/rubber/role/db/rubber-xtrarestore.sh
521
+ - templates/xtrabackup/config/rubber/rubber-xtrabackup.yml
522
+ - templates/xtrabackup/templates.rb
523
+ - templates/xtrabackup/templates.yml
461
524
  - test/cloud/aws_table_store_test.rb
462
525
  - test/cloud/aws_test.rb
463
526
  - test/cloud/fog_storage_test.rb
@@ -506,7 +569,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
506
569
  version: '0'
507
570
  segments:
508
571
  - 0
509
- hash: -1969407401613214093
572
+ hash: 4223981313086308948
510
573
  required_rubygems_version: !ruby/object:Gem::Requirement
511
574
  none: false
512
575
  requirements:
@@ -515,43 +578,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
515
578
  version: 1.3.1
516
579
  requirements: []
517
580
  rubyforge_project: rubber
518
- rubygems_version: 1.8.15
581
+ rubygems_version: 1.8.19
519
582
  signing_key:
520
583
  specification_version: 3
521
584
  summary: A capistrano plugin for managing multi-instance deployments to the cloud
522
585
  (ec2)
523
- test_files:
524
- - test/cloud/aws_table_store_test.rb
525
- - test/cloud/aws_test.rb
526
- - test/cloud/fog_storage_test.rb
527
- - test/cloud/fog_test.rb
528
- - test/command_test.rb
529
- - test/dns/fog_test.rb
530
- - test/environment_test.rb
531
- - test/fixtures/basic/common/bar.conf
532
- - test/fixtures/basic/common/foo.conf
533
- - test/fixtures/basic/host/host1/foo.conf
534
- - test/fixtures/basic/host/host2/foo.conf
535
- - test/fixtures/basic/role/role1/foo.conf
536
- - test/fixtures/basic/role/role2/foo.conf
537
- - test/fixtures/basic/rubber-extra.yml
538
- - test/fixtures/basic/rubber.yml
539
- - test/fixtures/expansion/rubber.yml
540
- - test/fixtures/generator_order/common/a_first.conf
541
- - test/fixtures/generator_order/common/z_last.conf
542
- - test/fixtures/generator_order/host/host1/a_first.conf
543
- - test/fixtures/generator_order/host/host1/z_last.conf
544
- - test/fixtures/generator_order/role/role1/a_first.conf
545
- - test/fixtures/generator_order/role/role1/z_last.conf
546
- - test/fixtures/generator_order/role/role2/a_first.conf
547
- - test/fixtures/generator_order/role/role2/z_last.conf
548
- - test/fixtures/instance_expansion/instance-test.yml
549
- - test/fixtures/instance_expansion/rubber.yml
550
- - test/fixtures/nested/rubber.yml
551
- - test/fixtures/secret/rubber.yml
552
- - test/fixtures/secret/secret.yml
553
- - test/generator_test.rb
554
- - test/instance_test.rb
555
- - test/test-rails-template.rb
556
- - test/test_helper.rb
557
- - test/util_test.rb
586
+ test_files: []