diff --git a/src/main/resources/plugins/plugins b/src/main/resources/plugins/plugins deleted file mode 100644 index 633f81f..0000000 --- a/src/main/resources/plugins/plugins +++ /dev/null @@ -1 +0,0 @@ -gitbucket-gist-plugin_2.12-4.9.0.jar diff --git a/src/main/resources/plugins/plugins.json b/src/main/resources/plugins/plugins.json new file mode 100644 index 0000000..3cde815 --- /dev/null +++ b/src/main/resources/plugins/plugins.json @@ -0,0 +1,6 @@ +[ + { + "filename": "gitbucket-gist-plugin_2.12-4.9.0.jar", + "default": true + } +] diff --git a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala index 02cc13c..1750af2 100644 --- a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala +++ b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala @@ -2,8 +2,7 @@ import java.io.{File, FilenameFilter, InputStream} import java.net.URLClassLoader -import java.nio.channels.{FileChannel, FileLock} -import java.nio.file.{Files, Paths, StandardOpenOption, StandardWatchEventKinds} +import java.nio.file.{Files, Paths, StandardWatchEventKinds} import java.util.Base64 import javax.servlet.ServletContext @@ -238,25 +237,6 @@ } } -// private def copyFile(from: File, to: File, retry: Int = 0): Unit = { -// using(FileChannel.open(from.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE)){ fc => -// using(fc.tryLock()){ lock => -// if(lock == null){ -// if(retry >= 3){ // Retry max 3 times -// logger.info(s"Retire to install plugin: ${from.getAbsolutePath}") -// } else { -// logger.info(s"Retry ${retry + 1} to install plugin: ${from.getAbsolutePath}") -// Thread.sleep(500) -// copyFile(from, to, retry + 1) -// } -// } else { -// logger.info(s"Install plugin: ${from.getAbsolutePath}") -// FileUtils.copyFile(from, to) -// } -// } -// } -// } - private class PluginJarFileFilter extends FilenameFilter { override def accept(dir: File, name: String): Boolean = name.endsWith(".jar") } diff --git a/src/main/scala/gitbucket/core/servlet/InitializeListener.scala b/src/main/scala/gitbucket/core/servlet/InitializeListener.scala index 68400d5..2597eae 100644 --- a/src/main/scala/gitbucket/core/servlet/InitializeListener.scala +++ b/src/main/scala/gitbucket/core/servlet/InitializeListener.scala @@ -18,11 +18,14 @@ import org.apache.commons.io.{FileUtils, IOUtils} import org.slf4j.LoggerFactory +import org.json4s._ +import org.json4s.jackson.JsonMethods._ import akka.actor.{Actor, ActorSystem, Props} import com.typesafe.akka.extension.quartz.QuartzSchedulerExtension import scala.collection.JavaConverters._ + /** * Initialize GitBucket system. * Update database schema and load plug-ins automatically in the context initializing. @@ -57,44 +60,11 @@ val manager = new JDBCVersionManager(conn) // Check version - val versionFile = new File(GitBucketHome, "version") - - if(versionFile.exists()){ - val version = FileUtils.readFileToString(versionFile, "UTF-8") - if(version == "3.14"){ - // Initialization for GitBucket 3.14 - logger.info("Migration to GitBucket 4.x start") - - // Backup current data - val dataMvFile = new File(GitBucketHome, "data.mv.db") - if(dataMvFile.exists) { - FileUtils.copyFile(dataMvFile, new File(GitBucketHome, "data.mv.db_3.14")) - } - val dataTraceFile = new File(GitBucketHome, "data.trace.db") - if(dataTraceFile.exists) { - FileUtils.copyFile(dataTraceFile, new File(GitBucketHome, "data.trace.db_3.14")) - } - - // Change form - manager.initialize() - manager.updateVersion(GitBucketCoreModule.getModuleId, "4.0.0") - conn.select("SELECT PLUGIN_ID, VERSION FROM PLUGIN"){ rs => - manager.updateVersion(rs.getString("PLUGIN_ID"), rs.getString("VERSION")) - } - conn.update("DROP TABLE PLUGIN") - versionFile.delete() - - logger.info("Migration to GitBucket 4.x completed") - - } else { - throw new Exception("GitBucket can't migrate from this version. Please update to 3.14 at first.") - } - } + checkVersion(manager, conn) // Run normal migration logger.info("Start schema update") - val solidbase = new Solidbase() - solidbase.migrate(conn, Thread.currentThread.getContextClassLoader, DatabaseConfig.liquiDriver, GitBucketCoreModule) + new Solidbase().migrate(conn, Thread.currentThread.getContextClassLoader, DatabaseConfig.liquiDriver, GitBucketCoreModule) // Rescue code for users who updated from 3.14 to 4.0.0 // https://github.com/gitbucket/gitbucket/issues/1227 @@ -110,24 +80,7 @@ } // Install bundled plugins - logger.info("Install bundled plugins") - val cl = Thread.currentThread.getContextClassLoader - try { - using(cl.getResourceAsStream("plugins/plugins")){ pluginsFile => - val pluginRepositoryDir = new File(PluginHome, ".repository") - if(!pluginRepositoryDir.exists){ - pluginRepositoryDir.mkdirs() - } - val plugins = IOUtils.toString(pluginsFile, "UTF-8").split("\n").map(_.trim) - plugins.collect { case plugin if plugin.nonEmpty && !plugin.startsWith("#") => - val file = new File(pluginRepositoryDir, plugin) - logger.info(s"Copy ${plugin} to ${file.getAbsolutePath}") - using(cl.getResourceAsStream("plugins/" + plugin), new FileOutputStream(file)){ case (in, out) => IOUtils.copy(in, out) } - } - } - } catch { - case e: Exception => logger.error("Error in installing bundled plugin", e) - } + installBundledPlugins() // Load plugins logger.info("Initialize plugins") @@ -140,7 +93,74 @@ scheduler.schedule("Daily", system.actorOf(Props[DeleteOldActivityActor]), "DeleteOldActivity") } + private def checkVersion(manager: JDBCVersionManager, conn: java.sql.Connection): Unit = { + logger.info("Check version") + val versionFile = new File(GitBucketHome, "version") + if(versionFile.exists()){ + val version = FileUtils.readFileToString(versionFile, "UTF-8") + if(version == "3.14"){ + // Initialization for GitBucket 3.14 + logger.info("Migration to GitBucket 4.x start") + + // Backup current data + val dataMvFile = new File(GitBucketHome, "data.mv.db") + if(dataMvFile.exists) { + FileUtils.copyFile(dataMvFile, new File(GitBucketHome, "data.mv.db_3.14")) + } + val dataTraceFile = new File(GitBucketHome, "data.trace.db") + if(dataTraceFile.exists) { + FileUtils.copyFile(dataTraceFile, new File(GitBucketHome, "data.trace.db_3.14")) + } + + // Change form + manager.initialize() + manager.updateVersion(GitBucketCoreModule.getModuleId, "4.0.0") + conn.select("SELECT PLUGIN_ID, VERSION FROM PLUGIN"){ rs => + manager.updateVersion(rs.getString("PLUGIN_ID"), rs.getString("VERSION")) + } + conn.update("DROP TABLE PLUGIN") + versionFile.delete() + + logger.info("Migration to GitBucket 4.x completed") + + } else { + throw new Exception("GitBucket can't migrate from this version. Please update to 3.14 at first.") + } + } + } + + private def installBundledPlugins(): Unit = { + logger.info("Install bundled plugins") + val cl = Thread.currentThread.getContextClassLoader + try { + using(cl.getResourceAsStream("plugins/plugins.json")){ pluginsFile => + val pluginRepositoryDir = new File(PluginHome, ".repository") + if(!pluginRepositoryDir.exists){ + pluginRepositoryDir.mkdirs() + } + + implicit val formats = DefaultFormats + val plugins = parse(IOUtils.toString(pluginsFile, "UTF-8")).extract[Seq[Plugin]] + plugins.foreach { plugin => + val file = new File(pluginRepositoryDir, plugin.filename) + if(!file.exists){ + logger.info(s"Copy ${plugin} to ${file.getAbsolutePath}") + using(cl.getResourceAsStream("plugins/" + plugin), new FileOutputStream(file)){ case (in, out) => IOUtils.copy(in, out) } + + if(plugin.default){ + logger.info(s"Enable ${file.getName} in default") + FileUtils.copyFile(file, new File(PluginHome, plugin.filename)) + } + } + } + } + } catch { + case e: Exception => logger.error("Error in installing bundled plugin", e) + } + } + + case class Plugin(filename: String, default: Boolean = false) override def contextDestroyed(event: ServletContextEvent): Unit = { // Shutdown Quartz scheduler