From 8ee017c3fa1db45a3aca461bb22797e0e6a64367 Mon Sep 17 00:00:00 2001 From: Naoki Takezoe Date: Sat, 11 Mar 2017 22:59:55 +0900 Subject: [PATCH] Add uninstall plugin button --- .../controller/SystemSettingsController.scala | 9 ++ .../core/plugin/PluginRegistory.scala | 116 ++++++++++-------- .../gitbucket/core/admin/plugins.scala.html | 17 ++- 3 files changed, 92 insertions(+), 50 deletions(-) diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala index e47d0fc89..efc1cd86c 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -190,6 +190,15 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase { redirect("/admin/plugins") }) + post("/admin/plugins/:pluginId/_uninstall")(adminOnly { + val pluginId = params("pluginId") + PluginRegistry().getPlugins().find(_.pluginId == pluginId).foreach { plugin => + PluginRegistry.uninstall(pluginId, request.getServletContext, loadSystemSettings(), request2Session(request).conn) + flash += "info" -> s"${pluginId} was uninstalled." + } + redirect("/admin/plugins") + }) + get("/admin/users")(adminOnly { val includeRemoved = params.get("includeRemoved").map(_.toBoolean).getOrElse(false) val users = getAllUsers(includeRemoved) diff --git a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala index b02426587..40da20c51 100644 --- a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala +++ b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala @@ -160,7 +160,7 @@ object PluginRegistry { private var instance = new PluginRegistry() - private var watcher: PluginWatchThread = null +// private var watcher: PluginWatchThread = null /** * Returns the PluginRegistry singleton instance. @@ -176,6 +176,19 @@ object PluginRegistry { initialize(context, settings, conn) } + /** + * Uninstall a specified plugin. + */ + def uninstall(pluginId: String, context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit = synchronized { + instance.getPlugins().find(_.pluginId == pluginId).foreach { plugin => + shutdown(context, settings) + // TODO kick uninstall action here? + plugin.pluginJar.delete() + instance = new PluginRegistry() + initialize(context, settings, conn) + } + } + /** * Initializes all installed plugins. */ @@ -209,7 +222,9 @@ object PluginRegistry { pluginName = plugin.pluginName, pluginVersion = plugin.versions.last.getVersion, description = plugin.description, - pluginClass = plugin + pluginClass = plugin, + pluginJar = pluginJar, + classLoader = classLoader )) } catch { @@ -220,10 +235,10 @@ object PluginRegistry { } } - if(watcher == null){ - watcher = new PluginWatchThread(context) - watcher.start() - } +// if(watcher == null){ +// watcher = new PluginWatchThread(context) +// watcher.start() +// } } def shutdown(context: ServletContext, settings: SystemSettings): Unit = synchronized { @@ -234,6 +249,8 @@ object PluginRegistry { case e: Exception => { logger.error(s"Error during plugin shutdown", e) } + } finally { + pluginInfo.classLoader.close() } } } @@ -247,47 +264,50 @@ case class PluginInfo( pluginName: String, pluginVersion: String, description: String, - pluginClass: Plugin + pluginClass: Plugin, + pluginJar: File, + classLoader: URLClassLoader ) -class PluginWatchThread(context: ServletContext) extends Thread with SystemSettingsService { - import gitbucket.core.model.Profile.profile.blockingApi._ - - private val logger = LoggerFactory.getLogger(classOf[PluginWatchThread]) - - override def run(): Unit = { - val path = Paths.get(PluginHome) - val fs = path.getFileSystem - val watcher = fs.newWatchService - - val watchKey = path.register(watcher, - StandardWatchEventKinds.ENTRY_CREATE, - StandardWatchEventKinds.ENTRY_MODIFY, - StandardWatchEventKinds.ENTRY_DELETE, - StandardWatchEventKinds.OVERFLOW) - - logger.info("Start PluginWatchThread: " + path) - - try { - while (watchKey.isValid()) { - val detectedWatchKey = watcher.take() - if(detectedWatchKey != null){ - val events = detectedWatchKey.pollEvents() - events.forEach { event => - logger.info(event.kind + ": " + event.context) - } - gitbucket.core.servlet.Database() withTransaction { session => - logger.info("Reloading plugins...") - PluginRegistry.reload(context, loadSystemSettings(), session.conn) - } - } - detectedWatchKey.reset() - } - } catch { - case _: InterruptedException => () - } - - logger.info("Shutdown PluginWatchThread") - } - -} +//class PluginWatchThread(context: ServletContext) extends Thread with SystemSettingsService { +// import gitbucket.core.model.Profile.profile.blockingApi._ +// +// private val logger = LoggerFactory.getLogger(classOf[PluginWatchThread]) +// +// override def run(): Unit = { +// val path = Paths.get(PluginHome) +// val fs = path.getFileSystem +// val watcher = fs.newWatchService +// +// val watchKey = path.register(watcher, +// StandardWatchEventKinds.ENTRY_CREATE, +// StandardWatchEventKinds.ENTRY_MODIFY, +// StandardWatchEventKinds.ENTRY_DELETE, +// StandardWatchEventKinds.OVERFLOW) +// +// logger.info("Start PluginWatchThread: " + path) +// +// try { +// while (watchKey.isValid()) { +// val detectedWatchKey = watcher.take() +// val events = detectedWatchKey.pollEvents() +// +// events.forEach { event => +// logger.info(event.kind + ": " + event.context) +// } +// +// gitbucket.core.servlet.Database() withTransaction { session => +// logger.info("Reloading plugins...") +// PluginRegistry.reload(context, loadSystemSettings(), session.conn) +// } +// +// detectedWatchKey.reset() +// } +// } catch { +// case _: InterruptedException => watchKey.cancel() +// } +// +// logger.info("Shutdown PluginWatchThread") +// } +// +//} diff --git a/src/main/twirl/gitbucket/core/admin/plugins.scala.html b/src/main/twirl/gitbucket/core/admin/plugins.scala.html index 446bdfc29..4603d2ba8 100644 --- a/src/main/twirl/gitbucket/core/admin/plugins.scala.html +++ b/src/main/twirl/gitbucket/core/admin/plugins.scala.html @@ -2,10 +2,10 @@ @gitbucket.core.html.main("Plugins"){ @gitbucket.core.admin.html.menu("plugins") { @gitbucket.core.helper.html.information(info) -

Installed plugins

+

Installed plugins

@if(plugins.size > 0) {