diff --git a/src/config.rs b/src/config.rs index f0aaded..bf7a264 100644 --- a/src/config.rs +++ b/src/config.rs @@ -84,6 +84,8 @@ pub struct AuthenticationConfig { pub struct BaseAttributes { pub name: String, pub target_url: String, + #[serde(default)] + pub recovery: bool, } impl BaseAttributes { diff --git a/src/installer.rs b/src/installer.rs index e734113..99ddba3 100644 --- a/src/installer.rs +++ b/src/installer.rs @@ -459,6 +459,23 @@ impl InstallerFramework { } } + /// The special recovery mode for the Installer Framework. + pub fn new_recovery_mode(attrs: BaseAttributes, install_path: &Path) -> Self { + InstallerFramework { + base_attributes: BaseAttributes { + recovery: true, + ..attrs + }, + config: None, + database: InstallationDatabase::new(), + install_path: Some(install_path.to_path_buf()), + preexisting_install: true, + is_launcher: false, + burn_after_exit: false, + launcher_path: None, + } + } + /// Creates a new instance of the Installer Framework with a specified Config, managing /// a pre-existing installation. pub fn new_with_db(attrs: BaseAttributes, install_path: &Path) -> Result { diff --git a/src/main.rs b/src/main.rs index eb6a700..d3a83da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,7 +127,11 @@ fn main() { let metadata_file = current_path.join("metadata.json"); let mut framework = if metadata_file.exists() { info!("Using pre-existing metadata file: {:?}", metadata_file); - InstallerFramework::new_with_db(config, current_path).log_expect("Unable to parse metadata") + InstallerFramework::new_with_db(config.clone(), current_path).unwrap_or_else(|e| { + error!("Failed to load metadata: {:?}", e); + warn!("Entering recovery mode"); + InstallerFramework::new_recovery_mode(config, current_path) + }) } else { info!("Starting fresh install"); fresh_install = true; diff --git a/ui/mock-server.js b/ui/mock-server.js index 80c07fd..5eaa9ce 100644 --- a/ui/mock-server.js +++ b/ui/mock-server.js @@ -10,6 +10,7 @@ let maintenance = false let launcher = false let fileExists = false let darkMode = false +let recoveryMode = false function progressSimulation (res) { if (showError) { @@ -71,7 +72,7 @@ function returnConfig (res) { app.get('/api/attrs', (req, res) => { console.log('-- Get attrs') res.send( - { name: 'yuzu', target_url: 'https://raw.githubusercontent.com/j-selby/test-installer/master/config.linux.v2.toml' } + { name: 'yuzu', recovery: recoveryMode, target_url: 'https://raw.githubusercontent.com/j-selby/test-installer/master/config.linux.v2.toml' } ) }) @@ -161,6 +162,10 @@ process.argv.forEach((val, index) => { showError = true console.log('Simulating errors') break + case 'recovery': + recoveryMode = true + console.log('Simulating recovery mode') + break } }) diff --git a/ui/src/locales/en.json b/ui/src/locales/en.json index c9176fb..e01b9ac 100644 --- a/ui/src/locales/en.json +++ b/ui/src/locales/en.json @@ -57,6 +57,7 @@ "repair": "Repair", "uninstall":"Uninstall", "view_local_files": "View local files", + "prompt_recover": "Installer data for {name} is corrupted.
A repair is required to restore the installation.", "prompt":"Are you sure you want to uninstall {name}?", "prompt_confirm":"Uninstall {name}" }, diff --git a/ui/src/views/ModifyView.vue b/ui/src/views/ModifyView.vue index a19e201..40947a9 100644 --- a/ui/src/views/ModifyView.vue +++ b/ui/src/views/ModifyView.vue @@ -38,7 +38,22 @@ export default { data: function () { return {} }, + mounted: function () { + if (this.$root.$data.attrs.recovery) { + this.recovery() + } + }, methods: { + recovery: function () { + this.$buefy.dialog.alert({ + title: this.$t('modify.repair'), + message: this.$t('modify.prompt_recover', { name: this.$root.$data.attrs.name }), + confirmText: this.$t('continue'), + type: 'is-danger', + hasIcon: true, + onConfirm: this.repair_packages + }) + }, update: function () { this.$router.push('/install/update/false') },