From b1f98caca2f6960f7abb3ef7f7c27b903e1ef929 Mon Sep 17 00:00:00 2001 From: pacien Date: Tue, 8 Dec 2020 16:10:42 +0100 Subject: app: add configuration directory migrator This adds an automatic configuration migrator which moves the configuration files previously located on the external public-ish directory to the private app storage, so that existing users can seamlessly transition to the next version. The cache directory containing the logs is cleared instead of being migrated, because those files are considered disposable. GitHub: related to #103 --- .../main/java/org/pacien/tincapp/context/App.kt | 9 ++-- .../context/ConfigurationDirectoryMigrator.kt | 63 ++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/org/pacien/tincapp/context/ConfigurationDirectoryMigrator.kt (limited to 'app/src') diff --git a/app/src/main/java/org/pacien/tincapp/context/App.kt b/app/src/main/java/org/pacien/tincapp/context/App.kt index 4d8d5d0..d825d78 100644 --- a/app/src/main/java/org/pacien/tincapp/context/App.kt +++ b/app/src/main/java/org/pacien/tincapp/context/App.kt @@ -28,6 +28,7 @@ import android.os.Handler import androidx.annotation.StringRes import org.pacien.tincapp.BuildConfig import org.pacien.tincapp.R +import org.slf4j.Logger import org.slf4j.LoggerFactory /** @@ -39,15 +40,17 @@ class App : Application() { appContext = applicationContext handler = Handler() AppLogger.configure() - setupCrashHandler() val logger = LoggerFactory.getLogger(this.javaClass) + setupCrashHandler(logger) + logger.info("Starting tinc app {} ({} build), running on {} ({})", BuildConfig.VERSION_NAME, BuildConfig.BUILD_TYPE, Build.VERSION.CODENAME, Build.VERSION.RELEASE) + + ConfigurationDirectoryMigrator().migrate() } - private fun setupCrashHandler() { - val logger = LoggerFactory.getLogger(this.javaClass) + private fun setupCrashHandler(logger: Logger) { val systemCrashHandler = Thread.getDefaultUncaughtExceptionHandler()!! val crashRecorder = CrashRecorder(logger, systemCrashHandler) Thread.setDefaultUncaughtExceptionHandler(crashRecorder) diff --git a/app/src/main/java/org/pacien/tincapp/context/ConfigurationDirectoryMigrator.kt b/app/src/main/java/org/pacien/tincapp/context/ConfigurationDirectoryMigrator.kt new file mode 100644 index 0000000..6ea914c --- /dev/null +++ b/app/src/main/java/org/pacien/tincapp/context/ConfigurationDirectoryMigrator.kt @@ -0,0 +1,63 @@ +/* + * Tinc App, an Android binding and user interface for the tinc mesh VPN daemon + * Copyright (C) 2017-2020 Pacien TRAN-GIRARD + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.pacien.tincapp.context + +import org.apache.commons.io.FileExistsException +import org.apache.commons.io.FileUtils +import org.slf4j.LoggerFactory + +/** + * Migrates the configuration from the external storage (used before version 0.32) to the internal storage. + * + * @author pacien + */ +class ConfigurationDirectoryMigrator { + private val log by lazy { LoggerFactory.getLogger(this.javaClass)!! } + private val context by lazy { App.getContext() } + private val paths = AppPaths + + fun migrate() { + migrateConfigurationDirectory() + migrateLogDirectory() + } + + private fun migrateConfigurationDirectory() { + val oldConfigDir = context.getExternalFilesDir(null) + if (oldConfigDir == null || oldConfigDir.listFiles().isNullOrEmpty()) return // nothing to do + + log.info("Configuration files present in old configuration directory at {}.", oldConfigDir.absolutePath) + for (oldConfig in oldConfigDir.listFiles() ?: emptyArray()) { + try { + log.info("Migrating {} to {}", oldConfig.absolutePath, paths.confDir()) + FileUtils.moveToDirectory(oldConfig, paths.confDir(), true) + } catch (e: FileExistsException) { + log.warn("Could not migrate {}: target already exists.", oldConfig.absolutePath) + } + } + } + + private fun migrateLogDirectory() { + val oldLogDir = context.externalCacheDir + if (oldLogDir == null || oldLogDir.listFiles().isNullOrEmpty()) return // nothing to do + + // There's no point moving the log files. Let's delete those instead. + log.info("Clearing old cache directory at {}", oldLogDir.absolutePath) + FileUtils.cleanDirectory(oldLogDir) + } +} -- cgit v1.2.3