Class: Chef::Knife::EcErrorHandler
- Inherits:
-
Object
- Object
- Chef::Knife::EcErrorHandler
- Defined in:
- lib/chef/knife/ec_error_handler.rb
Overview
This class handles the errors that we might encounter on a backup or restore, it stors the errors inside a specific file inside the working directory.
Instance Attribute Summary collapse
-
#err_file ⇒ Object
readonly
Returns the value of attribute err_file.
Instance Method Summary collapse
-
#add(ex) ⇒ Object
Add an exception to the error file.
- #display(file_name = @err_file) ⇒ Object
-
#initialize(working_dir, process) ⇒ EcErrorHandler
constructor
Creates a new instance of the EcErrorHandler to start adding errors during a backup or restore.
-
#lock_file(file_name, mode) ⇒ Object
Why lock the error file?.
Constructor Details
#initialize(working_dir, process) ⇒ EcErrorHandler
Creates a new instance of the EcErrorHandler to start adding errors during a backup or restore.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/chef/knife/ec_error_handler.rb', line 28 def initialize(working_dir, process) @err_dir = "#{working_dir}/errors" FileUtils.mkdir_p(@err_dir) # Create an specific error file name depending # of where the process comes from. @err_file = if process == Chef::Knife::EcRestore File.join(@err_dir, "restore-#{Time.now.iso8601}.json") elsif process == Chef::Knife::EcBackup File.join(@err_dir, "backup-#{Time.now.iso8601}.json") else File.join(@err_dir, "other-#{Time.now.iso8601}.json") end # exit handler at_exit { display(@err_file) } end |
Instance Attribute Details
#err_file ⇒ Object (readonly)
Returns the value of attribute err_file.
24 25 26 |
# File 'lib/chef/knife/ec_error_handler.rb', line 24 def err_file @err_file end |
Instance Method Details
#add(ex) ⇒ Object
Add an exception to the error file.
For now we are writing all the errors to a single file, but in the future we would like to be able to generate a full path just as we do when we are backing up the Server, just that putting the file inside ‘work_dir/errors/path`
Example: A failed user
> work_dir/errors/users/afiune.json
A failed cookbook
> work_dir/errors/cookbooks/burger.json
A failed environment
> work_dir/errors/environment/dev.json
The advantages of this schema is the ability to retry the backup or restore and pick up where we left.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/chef/knife/ec_error_handler.rb', line 63 def add(ex) msg = { timestamp: Time.now, message: ex., backtrace: ex.backtrace, exception: ex.class } if ex.respond_to?(:chef_rest_request=) && ex.chef_rest_request msg.merge!( req_path: ex.chef_rest_request.path, req_method: ex.chef_rest_request.method ) elsif ex.instance_of?(Chef::ChefFS::FileSystem::NotFoundError) msg.merge!( entry: ex.entry, cause: ex.cause, reason: ex.reason ) elsif ex.instance_of?(Chef::ChefFS::FileSystem::OperationFailedError) msg.merge!( entry: ex.entry, operation: ex.operation ) end lock_file(@err_file, 'a') do |f| f.write(Chef::JSONCompat.to_json_pretty(msg)) end end |
#display(file_name = @err_file) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/chef/knife/ec_error_handler.rb', line 111 def display(file_name = @err_file) # Print summary report only if error file exist return unless File.exist?(file_name) puts "\nError Summary Report" lock_file(file_name, 'r') do |f| f.each_line do |line| puts line end end puts "\nError(s) Summary file located at: '#{file_name}'" end |
#lock_file(file_name, mode) ⇒ Object
Why lock the error file?
Well because ec-backup has a concurrency options that will allow you to backup and restore things in parallel, therefor we need to ensure that only one process is writing to the error file.
100 101 102 103 104 105 106 107 108 109 |
# File 'lib/chef/knife/ec_error_handler.rb', line 100 def lock_file(file_name, mode) File.open(file_name, mode) do |f| begin f.flock ::File::LOCK_EX yield f ensure f.flock ::File::LOCK_UN end end end |