Support for removal of old backups automatically via a site setting

This commit is contained in:
Robin Ward 2014-03-11 17:28:12 -04:00
parent cf630207b7
commit dc1d6decf5
8 changed files with 86 additions and 21 deletions

View File

@ -49,9 +49,13 @@ class Admin::BackupsController < Admin::AdminController
end
def destroy
filename = params.fetch(:id)
Backup.remove(filename)
render nothing: true
backup = Backup[params.fetch(:id)]
if backup
backup.remove
render nothing: true
else
render nothing: true, status: 404
end
end
def logs

View File

@ -2,32 +2,29 @@ class Backup
include UrlHelper
include ActiveModel::SerializerSupport
attr_reader :filename, :size, :path, :link
attr_reader :filename
attr_accessor :size, :path, :link
def initialize(filename)
@filename = filename
@path = File.join(Backup.base_directory, filename)
@link = schemaless "#{Discourse.base_url}/admin/backups/#{filename}"
@size = File.size(@path)
end
def self.all
backups = Dir.glob(File.join(Backup.base_directory, "*.tar.gz"))
backups.sort.reverse.map { |backup| Backup.new(File.basename(backup)) }
backups.sort.reverse.map { |backup| Backup.create_from_filename(File.basename(backup)) }
end
def self.[](filename)
path = File.join(Backup.base_directory, filename)
if File.exists?(path)
Backup.new(filename)
Backup.create_from_filename(filename)
else
nil
end
end
def self.remove(filename)
path = File.join(Backup.base_directory, filename)
File.delete(path) if File.exists?(path)
def remove
File.delete(@path) if File.exists?(path)
end
def self.base_directory
@ -38,4 +35,18 @@ class Backup
File.join(Backup.base_directory, "tmp", identifier, "#{filename}.part#{chunk_number}")
end
def self.create_from_filename(filename)
Backup.new(filename).tap do |b|
b.path = File.join(Backup.base_directory, b.filename)
b.link = b.schemaless "#{Discourse.base_url}/admin/backups/#{b.filename}"
b.size = File.size(b.path)
end
end
def self.remove_old
all_backups = Backup.all
return unless all_backups.size > SiteSetting.maximum_backups
all_backups[SiteSetting.maximum_backups..-1].each {|b| b.remove}
end
end

View File

@ -1665,6 +1665,7 @@ en:
embedding: "Embedding"
legal: "Legal"
uncategorized: 'Uncategorized'
backups: "Backups"
lightbox:
download: "download"

View File

@ -712,6 +712,7 @@ en:
github_client_secret: "Client secret for Github authentication, registered at https://github.com/settings/applications"
allow_restore: "Allow restore, which can replace ALL site data! Leave false unless you plan to do restore a backup"
maximum_backups: "The maximum amount of backups to keep on disk. Older backups are automatically deleted"
active_user_rate_limit_secs: "How frequently we update the 'last_seen_at' field, in seconds"
previous_visit_timeout_hours: "How long a visit lasts before we consider it the 'previous' visit, in hours"

View File

@ -409,6 +409,14 @@ legal:
client: true
default: false
backups:
allow_restore:
client: true
default: false
maximum_backups:
client: true
default: 7
uncategorized:
faq_url:
@ -449,9 +457,6 @@ uncategorized:
summary_likes_required: 1
summary_percent_filter: 20
send_welcome_message: true
allow_restore:
client: true
default: false
educate_until_posts:
client: true
default: 2

View File

@ -38,6 +38,8 @@ module Export
create_archive
remove_old
notify_user
rescue SystemExit
log "Backup process was cancelled!"
@ -240,6 +242,11 @@ module Export
SystemMessage.create(@user, :export_succeeded)
end
def remove_old
log "Removing old backups..."
Backup.remove_old
end
def clean_up
log "Cleaning stuff up..."
remove_tmp_directory

View File

@ -36,7 +36,6 @@ describe Admin::BackupsController do
context "json format" do
it "returns a list of all the backups" do
File.stubs(:size).returns(42)
Backup.expects(:all).returns([Backup.new("backup1"), Backup.new("backup2")])
xhr :get, :index, format: :json
@ -104,9 +103,7 @@ describe Admin::BackupsController do
it "uses send_file to transmit the backup" do
controller.stubs(:render) # we need this since we're stubing send_file
File.stubs(:size).returns(42)
backup = Backup.new("backup42")
Backup.expects(:[]).with(backup_filename).returns(backup)
subject.expects(:send_file).with(backup.path)
@ -125,14 +122,22 @@ describe Admin::BackupsController do
describe ".destroy" do
it "removes the backup" do
Backup.expects(:remove).with(backup_filename)
let(:b) { Backup.new(backup_filename) }
it "removes the backup if found" do
Backup.expects(:[]).with(backup_filename).returns(b)
b.expects(:remove)
xhr :delete, :destroy, id: backup_filename
response.should be_success
end
it "doesn't remove the backup if not found" do
Backup.expects(:[]).with(backup_filename).returns(nil)
b.expects(:remove).never
xhr :delete, :destroy, id: backup_filename
response.should_not be_success
end
end
describe ".logs" do

View File

@ -0,0 +1,31 @@
require 'spec_helper'
require_dependency 'backup'
describe Backup do
let(:b1) { Backup.new('backup1') }
let(:b2) { Backup.new('backup2') }
let(:b3) { Backup.new('backup3') }
before do
Backup.stubs(:all).returns([b1, b2, b3])
end
context '#remove_old' do
it "does nothing if there aren't more backups than the setting" do
SiteSetting.stubs(:maximum_backups).returns(3)
Backup.any_instance.expects(:remove).never
Backup.remove_old
end
it "calls remove on the backups over our limit" do
SiteSetting.stubs(:maximum_backups).returns(1)
b1.expects(:remove).never
b2.expects(:remove).once
b3.expects(:remove).once
Backup.remove_old
end
end
end