MM-62746: drop manual plugin deployment support (#30019)

We no longer support system administrators  manually unpacking plugins into the server's working directory for plugins. Instead, the server will be free to remove folders and files from this directory at will as it synchronizes installed plugins from the prepackaged cache and filestore.

Fixes: https://mattermost.atlassian.net/browse/MM-62746

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Jesse Hallam
2025-07-16 01:46:41 +00:00
committed by GitHub
co-authored by Mattermost Build
parent b29e913953
commit 5c3a67b110
3 changed files with 9 additions and 41 deletions
+3 -11
View File
@@ -284,17 +284,9 @@ func (ch *Channels) syncPlugins() *model.AppError {
logger := ch.srv.Log().With(mlog.String("plugin_id", pluginID))
// Only handle managed plugins with .filestore flag file.
_, err := os.Stat(filepath.Join(*ch.cfgSvc.Config().PluginSettings.Directory, pluginID, managedPluginFileName))
if os.IsNotExist(err) {
logger.Warn("Skipping sync for unmanaged plugin")
} else if err != nil {
logger.Error("Skipping sync for plugin after failure to check if managed", mlog.Err(err))
} else {
logger.Info("Removing local installation of managed plugin before sync")
if err := ch.removePluginLocally(pluginID); err != nil {
logger.Error("Failed to remove local installation of managed plugin before sync", mlog.Err(err))
}
logger.Info("Removing local installation of managed plugin before sync")
if err := ch.removePluginLocally(pluginID); err != nil {
logger.Error("Failed to remove local installation of managed plugin before sync", mlog.Err(err))
}
}(plugin.Manifest.Id)
}
+6 -26
View File
@@ -12,7 +12,6 @@
// - plugins prepackged with the server in the prepackaged_plugins/ directory
// - plugins transitionally prepackaged with the server in the prepackaged_plugins/ directory
// - plugins installed to the filestore (amazons3 or local, alongisde files and images)
// - unmanaged plugins manually extracted to the confgured local directory
// ┌────────────────────────────┐
// │ ┌────────────────────────┐ │
// │ │prepackaged_plugins/ │ │
@@ -23,14 +22,11 @@
// │ │ │
// │ ▼ │
// │ ┌────────────────────────┐ │
// │ │plugins/ │ │
// │ │ unmanaged/ │ │
// │ │ filestore/ │ │ ┌────────────────────────┐
// │ │ .filestore │ │ │s3://bucket/plugins/ │
// │ │plugins/ │ │ ┌────────────────────────┐
// │ │ filestore/ │ │ │s3://bucket/plugins/ │
// │ │ prepackaged/ │◀┼───│ filestore.tar.gz │
// │ │ .filestore │ │ │ transitional.tar.gz │
// │ │ transitional/ │ │ └────────────────────────┘
// │ │ .filestore │ │
// │ │ transitional/ │ │ │ transitional.tar.gz │
// │ │ │ │ └────────────────────────┘
// │ └────────────────────────┘ │
// │ ┌────────┤
// │ │ server │
@@ -45,13 +41,8 @@
// release. On first startup, they are unpacked just like prepackaged plugins, but also get copied
// to the filestore. On future startups, the server uses the version in the filestore.
//
// Plugins are installed to the filestore when the user installs via the marketplace or manually
// uploads a plugin bundle. (Or because the plugin is transitionally prepackaged).
//
// Unmanaged plugins were manually extracted by into the configured local directory. This legacy
// method of installing plugins is distinguished from other extracted plugins by the absence of a
// flag file (.filestore). Managed plugins unconditionally override unmanaged plugins. A future
// version of Mattermost will likely drop support for unmanaged plugins.
// Plugins are installed to the filestore when the user installs via the marketplace or system
// console. (Or because the plugin is transitionally prepackaged).
//
// ### Enabling a Plugin
//
@@ -98,10 +89,6 @@ import (
"github.com/mattermost/mattermost/server/v8/platform/shared/filestore"
)
// managedPluginFileName is the file name of the flag file that marks
// a local plugin folder as "managed" by the file store.
const managedPluginFileName = ".filestore"
// fileStorePluginFolder is the folder name in the file store of the plugin bundles installed.
const fileStorePluginFolder = "plugins"
@@ -506,13 +493,6 @@ func (ch *Channels) installExtractedPlugin(manifest *model.Manifest, fromPluginD
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.mvdir.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
// Flag plugin locally as managed by the filestore.
f, err := os.Create(filepath.Join(bundlePath, managedPluginFileName))
if err != nil {
return nil, model.NewAppError("installExtractedPlugin", "app.plugin.flag_managed.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
f.Close()
if manifest.HasWebapp() {
updatedManifest, err := pluginsEnvironment.UnpackWebappBundle(manifest.Id)
if err != nil {
-4
View File
@@ -6458,10 +6458,6 @@
"id": "app.plugin.filesystem.app_error",
"translation": "Encountered filesystem error."
},
{
"id": "app.plugin.flag_managed.app_error",
"translation": "Unable to set plugin as managed by the file store."
},
{
"id": "app.plugin.get_cluster_plugin_statuses.app_error",
"translation": "Unable to get plugin statuses from the cluster."