From 9b64baf51e04ad65a1a65751650e4a11d37fc507 Mon Sep 17 00:00:00 2001 From: Akihiko Horiuchi <12ff5b8@gmail.com> Date: Thu, 14 Jan 2016 00:08:06 +0900 Subject: [PATCH] Add backup attribute to file resource (close #124) --- lib/itamae/resource/file.rb | 35 +++++++++++++++++++++++++++++ spec/integration/default_spec.rb | 7 +++++- spec/integration/recipes/default.rb | 5 +++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/itamae/resource/file.rb b/lib/itamae/resource/file.rb index 9fc253f4..114e10d1 100644 --- a/lib/itamae/resource/file.rb +++ b/lib/itamae/resource/file.rb @@ -3,12 +3,15 @@ module Itamae module Resource class File < Base + BACKUP_PATH = '/var/lib/itamae'.freeze + define_attribute :action, default: :create define_attribute :path, type: String, default_name: true define_attribute :content, type: String, default: nil define_attribute :mode, type: String define_attribute :owner, type: String define_attribute :group, type: String + define_attribute :backup, type: [FalseClass, Integer], default: 5 define_attribute :block, type: Proc, default: proc {} def pre_action @@ -56,6 +59,8 @@ def show_differences end def action_create(options) + backup if current.exist + if !current.exist && !@temppath run_command(["touch", attributes.path]) end @@ -91,6 +96,8 @@ def action_delete(options) end def action_edit(options) + backup if current.exist + if attributes.mode run_specinfra(:change_file_mode, @temppath, attributes.mode) else @@ -169,6 +176,34 @@ def send_tempfile f.unlink if f end end + + def backup + return unless (attributes.backup).kind_of?(FalseClass) ? false : attributes.backup > 0 + + savetime = Time.now.strftime('%Y%m%d%H%M%S') + basename = ::File.basename(attributes.path) + backup_filename = "#{basename}.itamae-#{savetime}" + backup_path = ::File.join(BACKUP_PATH, backup_filename) + + run_specinfra(:create_file_as_directory, ::File.dirname(backup_path)) + run_specinfra(:copy_file, attributes.path, backup_path) + Itamae.logger.info "#{attributes.path} backed up to #{backup_path}" + + backup_files = run_command(['ls', '-1', BACKUP_PATH]) + backup_files = backup_files.stdout.chomp.split("\n").select { |f| + f.match("#{basename}.itamae-") + }.sort { |a, b| + b <=> a + } + + if backup_files.length > attributes.backup + remainder = backup_files.slice(attributes.backup..-1) + remainder.each do |backup_to_delete| + run_specinfra(:remove_file, ::File.join(BACKUP_PATH, backup_to_delete)) + Itamae.logger.info "#{attributes.path} removed backup at #{backup_path}" + end + end + end end end end diff --git a/spec/integration/default_spec.rb b/spec/integration/default_spec.rb index 800fe229..1ba08dcc 100644 --- a/spec/integration/default_spec.rb +++ b/spec/integration/default_spec.rb @@ -51,9 +51,14 @@ end end +describe command('cat /var/itamae/backup/file.itamae-*') do + its(:exit_status) { should eq(0) } + its(:stdout) { should match(/Hello World/) } +end + describe file('/tmp/file') do it { should be_file } - its(:content) { should match(/Hello World/) } + its(:content) { should match(/Hello New World/) } it { should be_mode 777 } end diff --git a/spec/integration/recipes/default.rb b/spec/integration/recipes/default.rb index 432ad7cc..342c3e6e 100644 --- a/spec/integration/recipes/default.rb +++ b/spec/integration/recipes/default.rb @@ -148,6 +148,11 @@ mode "777" end +file "/tmp/file" do + content "Hello New World" + mode "777" +end + execute "echo 'Hello Execute' > /tmp/execute" file "/tmp/never_exist1" do