-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementing backup of broken config files #462
base: master
Are you sure you want to change the base?
Conversation
r? @dhylands |
let mut backup_name = file_name.to_owned(); | ||
backup_name.push_str("_BROKEN"); | ||
warn!("Moving broken config file to {}", backup_name); | ||
let _ = fs::rename(file_name, &backup_name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think you should test the return code and instead of printing the "moving" warning, print a "Moved" or "Failed to move" message (since there are lots of reasons why the rename could fail).
r=me with that change.
And as fabrice suggests, adding tests would be good.
I implemented a test and an error check around moving the config file, but now I am having second thoughts. Now I tend to panicing the main thread when the config can't be parsed. The problem is that I don't know how to properly test that. I can write a simple test like #[test]
#[should_panic]
fn config_service_should_panic_with_broken_config() {
use std::fs;
use std::io::Write;
use std::path::Path;
// Create broken config file
let broken_conf = "{\"foo\":\"bar\",}".to_owned();
let mut file = fs::File::create(&Path::new(&config_file_name)).ok().unwrap();
let _ = file.write_all(&broken_conf.as_bytes());
// Should panic:
let config = ConfigService::new(&config_file_name);
// Will litter temp file, because this is never reached:
fs::remove_file(config_file_name).unwrap_or(());
} but this will litter the temp file because the removal line is never reached. How to work around this? |
You can set a panic handler which does the cleanup. |
I don't know how tests are organized internally, but this might lead to the same problem in disguise: You might need to remove the handler to prevent interference with other |
@dhylands is raising a good point here:
I don't think that we can reasonably recover from the full disk / incomplete config write scenario and low-level user intervention is unavoidable. In such a case it may be better to fail really hard vs. fail just subtly. Problem is that loading the config happens so early in the startup process that we can't even inform the clients unless we implement a few ugly workarounds. I really see three options:
The second option is close to what was in place so far, plus some rather complex lookup logic looking for good copies of the config. The third option seems desirable, but it requires major changes to several parts of foxbox and likely a good deal of new architectural feats that we don't have yet. For now, the first solution may be the cleanest. |
take_handler allows you to retrieve the previous handler which could be reinstalled after you've done your test. You could also use RAII and create an object whose drop method does the cleanup. |
This addresses issue fxbox#390.
I implemented behavior number 2 as outlined above. That way foxbox can run and potentially start some form of diagnostic mode in the future. I guess we'll need a getter for the logs soon? r? @fabrice |
This addresses #390.
The new behavior is to move the broken config file to
foxbox.conf_BROKEN
before continuing with an empty config that would ultimately have overwritten the broken one.