Skip to content

Commit e40a5c2

Browse files
committed
Add backup attribute to file resource (close #124)
1 parent c4ec051 commit e40a5c2

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

lib/itamae/resource/file.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
module Itamae
44
module Resource
55
class File < Base
6+
BACKUP_PATH = '/var/itamae/backup'.freeze
7+
68
define_attribute :action, default: :create
79
define_attribute :path, type: String, default_name: true
810
define_attribute :content, type: String, default: nil
911
define_attribute :mode, type: String
1012
define_attribute :owner, type: String
1113
define_attribute :group, type: String
14+
define_attribute :backup, type: [FalseClass, Integer], default: 5
1215
define_attribute :block, type: Proc, default: proc {}
1316

1417
def pre_action
@@ -56,6 +59,8 @@ def show_differences
5659
end
5760

5861
def action_create(options)
62+
backup if current.exist
63+
5964
if !current.exist && !@temppath
6065
run_command(["touch", attributes.path])
6166
end
@@ -91,6 +96,8 @@ def action_delete(options)
9196
end
9297

9398
def action_edit(options)
99+
backup if current.exist
100+
94101
if attributes.mode
95102
run_specinfra(:change_file_mode, @temppath, attributes.mode)
96103
else
@@ -169,6 +176,34 @@ def send_tempfile
169176
f.unlink if f
170177
end
171178
end
179+
180+
def backup
181+
return unless (attributes.backup).kind_of?(FalseClass) ? false : attributes.backup > 0
182+
183+
savetime = Time.now.strftime('%Y%m%d%H%M%S')
184+
backup_filename = "#{attributes.path}.itamae-#{savetime}"
185+
backup_path = ::File.join(BACKUP_PATH, backup_filename)
186+
backup_directory = ::File.dirname(backup_path)
187+
188+
run_specinfra(:create_file_as_directory, backup_directory)
189+
run_specinfra(:copy_file, attributes.path, backup_path)
190+
Itamae.logger.info "#{attributes.path} backed up to #{backup_path}"
191+
192+
basename = ::File.basename(attributes.path)
193+
backup_files = run_command(['ls', '-1', backup_directory])
194+
backup_files = backup_files.stdout.chomp.split("\n").select { |f|
195+
f.match(/\A#{basename}.itamae-[0-9]+\z/)
196+
}.reverse
197+
198+
if backup_files.length > attributes.backup
199+
remainder = backup_files.slice(attributes.backup..-1)
200+
remainder.each do |backup_to_delete|
201+
backup_to_delete = ::File.join(backup_directory, backup_to_delete)
202+
run_specinfra(:remove_file, backup_to_delete)
203+
Itamae.logger.info "#{attributes.path} removed backup at #{backup_to_delete}"
204+
end
205+
end
206+
end
172207
end
173208
end
174209
end

spec/integration/default_spec.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,13 @@
5151
end
5252
end
5353

54+
describe file('/var/itamae/backup/tmp') do
55+
it { should be_directory }
56+
end
57+
5458
describe file('/tmp/file') do
5559
it { should be_file }
56-
its(:content) { should match(/Hello World/) }
60+
its(:content) { should match(/Hello New World/) }
5761
it { should be_mode 777 }
5862
end
5963

spec/integration/recipes/default.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@
148148
mode "777"
149149
end
150150

151+
file "/tmp/file" do
152+
content "Hello New World"
153+
mode "777"
154+
end
155+
151156
execute "echo 'Hello Execute' > /tmp/execute"
152157

153158
file "/tmp/never_exist1" do

0 commit comments

Comments
 (0)