Skip to content

Commit

Permalink
Only restore backups created after boot
Browse files Browse the repository at this point in the history
  • Loading branch information
dgdavid committed Sep 12, 2018
1 parent aff448e commit 6ec9d20
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
24 changes: 19 additions & 5 deletions src/modules/Update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -801,16 +801,25 @@ def clean_backup
:force => true, :secure => true)
end

# restores backup
# Restores valid backups
#
# It will look for "restore-*.sh" files inside the BACKUP_DIR, executing only those created
# after last boot (bsc#1097297)
def restore_backup
log.info "Restoring backup"
mounted_root = Installation.destdir
script_glob = File.join(mounted_root, BACKUP_DIR,"restore-*.sh")
script_glob = File.join(mounted_root, BACKUP_DIR, "restore-*.sh")
# sort the scripts to execute them in the expected order
::Dir.glob(script_glob).sort.each do |path|
cmd = "sh #{path} #{File.join("/", mounted_root)}"
res = SCR.Execute(path(".target.bash_output"), cmd)
log.info "Restoring with script #{cmd} result: #{res}"
backup_time = File.stat(path).ctime.to_i

if boot_time < backup_time
cmd = "sh #{path} #{File.join("/", mounted_root)}"
res = SCR.Execute(path(".target.bash_output"), cmd)
log.info "Restoring with script #{cmd} result: #{res}"
else
log.info "Discarding #{path} (created before last boot)"
end
end
end

Expand Down Expand Up @@ -850,6 +859,11 @@ def restore_backup

private

# @return [Integer] boot time found in /proc/stat
def boot_time
@boot_time ||= IO.read("/proc/stat")[/btime.*/].split.last.to_i
end

def create_tarball(tarball_path, root, paths)
# tar reports an error if a file does not exist.
# So we have to check this before.
Expand Down
39 changes: 33 additions & 6 deletions test/update_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,39 @@ def default_SetDesktopPattern_stubs
end

describe "#restore_backup" do
it "call all restore scripts in backup directory" do
expect(::Dir).to receive(:glob).and_return(["restore-a.sh", "restore-b.sh"])
expect(Yast::SCR).to receive(:Execute).with(Yast::Path.new(".target.bash_output"), /sh .*restore-a.sh \/mnt/).
and_return({"exit" => 0})
expect(Yast::SCR).to receive(:Execute).with(Yast::Path.new(".target.bash_output"), /sh .*restore-b.sh \/mnt/).
and_return({"exit" => 0})
let(:boot_time) { 1514764800 }
let(:valid_backup_time) { boot_time + 1000 }
let(:invalid_backup_time) { boot_time - 1000 }
let(:first_backup) { "000-restore-c.sh" }
let(:second_backup) { "restore-a.sh" }
let(:third_backup) { "restore-b.sh" }
let(:mock_stat) { double({ ctime: nil }) }

before do
allow(::Dir).to receive(:glob).and_return([third_backup, first_backup, second_backup])

allow(::File).to receive(:stat).with(anything).and_return(mock_stat)
allow(mock_stat).to receive(:ctime)
.and_return(valid_backup_time, valid_backup_time, invalid_backup_time)

allow(Yast::Update).to receive(:boot_time).and_return(boot_time)
end

it "found all available backups" do
expect(::Dir).to receive(:glob).and_return(["restore-b.sh", "000-restore-c.sh", "restore-a.sh"])

Yast::Update.restore_backup
end

it "execute only backups created after boot" do
expect(Yast::SCR).to receive(:Execute)
.with(Yast::Path.new(".target.bash_output"), /sh .*000-restore-c.sh \/mnt/)
.and_return({"exit" => 0})
expect(Yast::SCR).to receive(:Execute)
.with(Yast::Path.new(".target.bash_output"), /sh .*restore-a.sh \/mnt/)
.and_return({"exit" => 0})
expect(Yast::SCR).to_not receive(:Execute)
.with(Yast::Path.new(".target.bash_output"), /sh .*restore-b.sh \/mnt/)

Yast::Update.restore_backup
end
Expand Down

0 comments on commit 6ec9d20

Please sign in to comment.