rubber 2.0.0.pre9 → 2.0.0.pre10

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.
@@ -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: []