mirror of
https://github.com/gitbucket/gitbucket.git
synced 2026-01-09 09:02:16 +01:00
Enhance --plugin_dir option behavior
It became an option to specify an extra plugin jars directory, not to overwrite PLUGIN_HOME.
This commit is contained in:
@@ -24,7 +24,6 @@ import play.twirl.api.Html
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import com.github.zafarkhaja.semver.{Version => Semver}
|
||||
|
||||
class PluginRegistry {
|
||||
|
||||
@@ -190,6 +189,7 @@ object PluginRegistry {
|
||||
private var instance = new PluginRegistry()
|
||||
|
||||
private var watcher: PluginWatchThread = null
|
||||
private var extraWatcher: PluginWatchThread = null
|
||||
|
||||
/**
|
||||
* Returns the PluginRegistry singleton instance.
|
||||
@@ -242,6 +242,8 @@ object PluginRegistry {
|
||||
}).toSeq.sortBy(_.getName).reverse
|
||||
}
|
||||
|
||||
lazy val extraPluginDir: Option[String] = Option(System.getProperty("gitbucket.pluginDir"))
|
||||
|
||||
/**
|
||||
* Initializes all installed plugins.
|
||||
*/
|
||||
@@ -256,57 +258,65 @@ object PluginRegistry {
|
||||
}
|
||||
installedDir.mkdir()
|
||||
|
||||
if(pluginDir.exists && pluginDir.isDirectory) {
|
||||
pluginDir.listFiles(new FilenameFilter {
|
||||
override def accept(dir: File, name: String): Boolean = name.endsWith(".jar")
|
||||
}).toSeq.sortBy(_.getName).reverse.foreach { pluginJar =>
|
||||
val pluginJars = listPluginJars(pluginDir)
|
||||
val extraJars = extraPluginDir.map { extraDir => listPluginJars(new File(extraDir)) }.getOrElse(Nil)
|
||||
|
||||
val installedJar = new File(installedDir, pluginJar.getName)
|
||||
FileUtils.copyFile(pluginJar, installedJar)
|
||||
(extraJars ++ pluginJars).foreach { pluginJar =>
|
||||
val installedJar = new File(installedDir, pluginJar.getName)
|
||||
FileUtils.copyFile(pluginJar, installedJar)
|
||||
|
||||
logger.info(s"Initialize ${pluginJar.getName}")
|
||||
val classLoader = new URLClassLoader(Array(installedJar.toURI.toURL), Thread.currentThread.getContextClassLoader)
|
||||
try {
|
||||
val plugin = classLoader.loadClass("Plugin").getDeclaredConstructor().newInstance().asInstanceOf[Plugin]
|
||||
val pluginId = plugin.pluginId
|
||||
// Check duplication
|
||||
instance.getPlugins().find(_.pluginId == pluginId).foreach { x =>
|
||||
throw new IllegalStateException(s"Plugin ${pluginId} is duplicated. ${x.pluginJar.getName} is available.")
|
||||
logger.info(s"Initialize ${pluginJar.getName}")
|
||||
val classLoader = new URLClassLoader(Array(installedJar.toURI.toURL), Thread.currentThread.getContextClassLoader)
|
||||
try {
|
||||
val plugin = classLoader.loadClass("Plugin").getDeclaredConstructor().newInstance().asInstanceOf[Plugin]
|
||||
val pluginId = plugin.pluginId
|
||||
|
||||
// Check duplication
|
||||
instance.getPlugins().find(_.pluginId == pluginId) match {
|
||||
case Some(x) => {
|
||||
logger.warn(s"Plugin ${pluginId} is duplicated. ${x.pluginJar.getName} is available.")
|
||||
}
|
||||
case None => {
|
||||
// Migration
|
||||
val solidbase = new Solidbase()
|
||||
solidbase.migrate(conn, classLoader, DatabaseConfig.liquiDriver, new Module(plugin.pluginId, plugin.versions: _*))
|
||||
|
||||
// Migration
|
||||
val solidbase = new Solidbase()
|
||||
solidbase.migrate(conn, classLoader, DatabaseConfig.liquiDriver, new Module(plugin.pluginId, plugin.versions: _*))
|
||||
// Check database version
|
||||
val databaseVersion = manager.getCurrentVersion(plugin.pluginId)
|
||||
val pluginVersion = plugin.versions.last.getVersion
|
||||
if (databaseVersion != pluginVersion) {
|
||||
throw new IllegalStateException(s"Plugin version is ${pluginVersion}, but database version is ${databaseVersion}")
|
||||
}
|
||||
|
||||
// Check database version
|
||||
val databaseVersion = manager.getCurrentVersion(plugin.pluginId)
|
||||
val pluginVersion = plugin.versions.last.getVersion
|
||||
if (databaseVersion != pluginVersion) {
|
||||
throw new IllegalStateException(s"Plugin version is ${pluginVersion}, but database version is ${databaseVersion}")
|
||||
// Initialize
|
||||
plugin.initialize(instance, context, settings)
|
||||
instance.addPlugin(PluginInfo(
|
||||
pluginId = plugin.pluginId,
|
||||
pluginName = plugin.pluginName,
|
||||
pluginVersion = plugin.versions.last.getVersion,
|
||||
description = plugin.description,
|
||||
pluginClass = plugin,
|
||||
pluginJar = pluginJar,
|
||||
classLoader = classLoader
|
||||
))
|
||||
}
|
||||
|
||||
// Initialize
|
||||
plugin.initialize(instance, context, settings)
|
||||
instance.addPlugin(PluginInfo(
|
||||
pluginId = plugin.pluginId,
|
||||
pluginName = plugin.pluginName,
|
||||
pluginVersion = plugin.versions.last.getVersion,
|
||||
description = plugin.description,
|
||||
pluginClass = plugin,
|
||||
pluginJar = pluginJar,
|
||||
classLoader = classLoader
|
||||
))
|
||||
|
||||
} catch {
|
||||
case e: Throwable => logger.error(s"Error during plugin initialization: ${pluginJar.getName}", e)
|
||||
}
|
||||
} catch {
|
||||
case e: Throwable => logger.error(s"Error during plugin initialization: ${pluginJar.getName}", e)
|
||||
}
|
||||
}
|
||||
|
||||
if(watcher == null){
|
||||
watcher = new PluginWatchThread(context)
|
||||
watcher = new PluginWatchThread(context, PluginHome)
|
||||
watcher.start()
|
||||
}
|
||||
|
||||
extraPluginDir.foreach { extraDir =>
|
||||
if(extraWatcher == null){
|
||||
extraWatcher = new PluginWatchThread(context, extraDir)
|
||||
extraWatcher.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def shutdown(context: ServletContext, settings: SystemSettings): Unit = synchronized {
|
||||
@@ -349,14 +359,14 @@ case class PluginInfo(
|
||||
classLoader: URLClassLoader
|
||||
) extends PluginInfoBase(pluginId, pluginName, pluginVersion, description)
|
||||
|
||||
class PluginWatchThread(context: ServletContext) extends Thread with SystemSettingsService {
|
||||
class PluginWatchThread(context: ServletContext, dir: String) extends Thread with SystemSettingsService {
|
||||
import gitbucket.core.model.Profile.profile.blockingApi._
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
private val logger = LoggerFactory.getLogger(classOf[PluginWatchThread])
|
||||
|
||||
override def run(): Unit = {
|
||||
val path = Paths.get(PluginHome)
|
||||
val path = Paths.get(dir)
|
||||
if(!Files.exists(path)){
|
||||
Files.createDirectories(path)
|
||||
}
|
||||
@@ -374,7 +384,9 @@ class PluginWatchThread(context: ServletContext) extends Thread with SystemSetti
|
||||
try {
|
||||
while (watchKey.isValid()) {
|
||||
val detectedWatchKey = watcher.take()
|
||||
val events = detectedWatchKey.pollEvents.asScala.filter(_.context.toString != ".installed")
|
||||
val events = detectedWatchKey.pollEvents.asScala.filter { e =>
|
||||
e.context.toString != ".installed" && !e.context.toString.endsWith(".bak")
|
||||
}
|
||||
if(events.nonEmpty){
|
||||
events.foreach { event =>
|
||||
logger.info(event.kind + ": " + event.context)
|
||||
|
||||
@@ -32,7 +32,7 @@ object Directory {
|
||||
|
||||
val DatabaseHome = s"${GitBucketHome}/data"
|
||||
|
||||
val PluginHome = Option(System.getProperty("gitbucket.pluginDir")).getOrElse(s"${GitBucketHome}/plugins")
|
||||
val PluginHome = s"${GitBucketHome}/plugins"
|
||||
|
||||
val TemporaryHome = s"${GitBucketHome}/tmp"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user