snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
This commit is contained in:
394
server/channels/app/support_packet.go
Normal file
394
server/channels/app/support_packet.go
Normal file
@@ -0,0 +1,394 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||
)
|
||||
|
||||
func (a *App) GenerateSupportPacket(rctx request.CTX, options *model.SupportPacketOptions) []model.FileData {
|
||||
functions := map[string]func(rctx request.CTX) (*model.FileData, error){
|
||||
"metadata": a.getSupportPacketMetadata,
|
||||
"stats": a.getSupportPacketStats,
|
||||
"jobs": a.getSupportPacketJobList,
|
||||
"permissions": a.getSupportPacketPermissionsInfo,
|
||||
"plugins": a.getPluginsFile,
|
||||
"schema": a.getSupportPacketDatabaseSchema,
|
||||
}
|
||||
|
||||
var (
|
||||
// If any errors we come across within this function, we will log it in a warning.txt file so that we know why certain files did not get produced if any
|
||||
warnings *multierror.Error
|
||||
// Creating an array of files that we are going to be adding to our zip file
|
||||
fileDatas []model.FileData
|
||||
wg sync.WaitGroup
|
||||
mut sync.Mutex // Protects warnings and fileDatas
|
||||
)
|
||||
|
||||
wg.Go(func() {
|
||||
for name, fn := range functions {
|
||||
fileData, err := fn(rctx)
|
||||
mut.Lock()
|
||||
if err != nil {
|
||||
rctx.Logger().Error("Failed to generate file for Support Packet",
|
||||
mlog.String("file", name),
|
||||
mlog.Err(err),
|
||||
)
|
||||
warnings = multierror.Append(warnings, err)
|
||||
}
|
||||
|
||||
if fileData != nil {
|
||||
fileDatas = append(fileDatas, *fileData)
|
||||
}
|
||||
mut.Unlock()
|
||||
}
|
||||
|
||||
// Generate platform support packet
|
||||
files, err := a.Srv().Platform().GenerateSupportPacket(rctx, options)
|
||||
mut.Lock()
|
||||
if err != nil {
|
||||
warnings = multierror.Append(warnings, err)
|
||||
}
|
||||
|
||||
if fileDatas != nil {
|
||||
if cluster := a.Cluster(); cluster != nil && *a.Config().ClusterSettings.Enable {
|
||||
hostname := cluster.GetMyClusterInfo().Hostname
|
||||
for _, file := range files {
|
||||
// When running in a cluster, the files are generated with the cluster node name as the directory, e.g. 7917b92f9e4c/mattermost.log
|
||||
fileDatas = append(fileDatas, model.FileData{
|
||||
Filename: filepath.Join(hostname, file.Filename),
|
||||
Body: file.Body,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// When running in standalone mode, all files are generated with the same directory name, e.g. mattermost.log.
|
||||
fileDatas = append(fileDatas, files...)
|
||||
}
|
||||
}
|
||||
mut.Unlock()
|
||||
})
|
||||
|
||||
// Run the cluster generation in a separate goroutine as CPU profile generation and file upload can take a long time
|
||||
if cluster := a.Cluster(); cluster != nil && *a.Config().ClusterSettings.Enable {
|
||||
wg.Go(func() {
|
||||
files, err := cluster.GenerateSupportPacket(rctx, options)
|
||||
mut.Lock()
|
||||
if err != nil {
|
||||
rctx.Logger().Error("Failed to generate Support Packet from cluster nodes", mlog.Err(err))
|
||||
warnings = multierror.Append(warnings, err)
|
||||
}
|
||||
|
||||
for _, node := range files {
|
||||
fileDatas = append(fileDatas, node...)
|
||||
}
|
||||
mut.Unlock()
|
||||
})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
pluginContext := pluginContext(rctx)
|
||||
a.ch.RunMultiHook(func(hooks plugin.Hooks, manifest *model.Manifest) bool {
|
||||
// If the plugin defined the support_packet prop it means there is a UI element to include it in the support packet.
|
||||
// Check if the plugin is in the list of plugins to include in the Support Packet.
|
||||
if _, ok := manifest.Props["support_packet"]; ok {
|
||||
if !slices.Contains(options.PluginPackets, manifest.Id) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, just call the hook as the plugin decided to always include it in the Support Packet.
|
||||
pluginData, err := hooks.GenerateSupportData(pluginContext)
|
||||
if err != nil {
|
||||
rctx.Logger().Warn("Failed to generate plugin file for Support Packet", mlog.String("plugin", manifest.Id), mlog.Err(err))
|
||||
warnings = multierror.Append(warnings, err)
|
||||
return true
|
||||
}
|
||||
|
||||
for _, data := range pluginData {
|
||||
fileDatas = append(fileDatas, *data)
|
||||
}
|
||||
|
||||
return true
|
||||
}, plugin.GenerateSupportDataID)
|
||||
|
||||
// Adding a warning.txt file to the fileDatas if any warning
|
||||
if warnings != nil {
|
||||
fileDatas = append(fileDatas, model.FileData{
|
||||
Filename: model.SupportPacketErrorFile,
|
||||
Body: []byte(warnings.Error()),
|
||||
})
|
||||
}
|
||||
|
||||
return fileDatas
|
||||
}
|
||||
|
||||
func (a *App) getSupportPacketStats(rctx request.CTX) (*model.FileData, error) {
|
||||
var (
|
||||
rErr *multierror.Error
|
||||
err error
|
||||
stats model.SupportPacketStats
|
||||
)
|
||||
|
||||
stats.RegisteredUsers, err = a.Srv().Store().User().Count(model.UserCountOptions{IncludeDeleted: true})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get registered user count"))
|
||||
}
|
||||
|
||||
stats.ActiveUsers, err = a.Srv().Store().User().Count(model.UserCountOptions{})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get active user count"))
|
||||
}
|
||||
|
||||
stats.DailyActiveUsers, err = a.Srv().Store().User().AnalyticsActiveCount(DayMilliseconds, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get daily active user count"))
|
||||
}
|
||||
|
||||
stats.MonthlyActiveUsers, err = a.Srv().Store().User().AnalyticsActiveCount(MonthMilliseconds, model.UserCountOptions{IncludeBotAccounts: false, IncludeDeleted: false})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get monthly active user count"))
|
||||
}
|
||||
|
||||
stats.DeactivatedUsers, err = a.Srv().Store().User().AnalyticsGetInactiveUsersCount()
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get deactivated user count"))
|
||||
}
|
||||
|
||||
stats.Guests, err = a.Srv().Store().User().AnalyticsGetGuestCount()
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get guest count"))
|
||||
}
|
||||
|
||||
stats.SingleChannelGuests, err = a.Srv().Store().User().AnalyticsGetSingleChannelGuestCount()
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get single channel guest count"))
|
||||
}
|
||||
|
||||
stats.BotAccounts, err = a.Srv().Store().User().Count(model.UserCountOptions{IncludeBotAccounts: true, ExcludeRegularUsers: true})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get bot acount count"))
|
||||
}
|
||||
|
||||
stats.Posts, err = a.Srv().Store().Post().AnalyticsPostCount(&model.PostCountOptions{})
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get post count"))
|
||||
}
|
||||
|
||||
openChannels, err := a.Srv().Store().Channel().AnalyticsTypeCount("", model.ChannelTypeOpen)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get open channels count"))
|
||||
}
|
||||
privateChannels, err := a.Srv().Store().Channel().AnalyticsTypeCount("", model.ChannelTypePrivate)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get private channels count"))
|
||||
}
|
||||
stats.Channels = openChannels + privateChannels
|
||||
|
||||
stats.Teams, err = a.Srv().Store().Team().AnalyticsTeamCount(nil)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get team count"))
|
||||
}
|
||||
|
||||
stats.SlashCommands, err = a.Srv().Store().Command().AnalyticsCommandCount("")
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get command count"))
|
||||
}
|
||||
|
||||
stats.IncomingWebhooks, err = a.Srv().Store().Webhook().AnalyticsIncomingCount("", "")
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get incoming webhook count"))
|
||||
}
|
||||
|
||||
stats.OutgoingWebhooks, err = a.Srv().Store().Webhook().AnalyticsOutgoingCount("")
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to get outgoing webhook count"))
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&stats)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to marshal Support Packet into yaml"))
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: "stats.yaml",
|
||||
Body: b,
|
||||
}
|
||||
return fileData, rErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (a *App) getSupportPacketJobList(rctx request.CTX) (*model.FileData, error) {
|
||||
const numberOfJobsRuns = 5
|
||||
|
||||
var (
|
||||
rErr *multierror.Error
|
||||
err error
|
||||
jobs model.SupportPacketJobList
|
||||
)
|
||||
|
||||
jobs.LDAPSyncJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeLdapSync, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting LDAP sync jobs"))
|
||||
}
|
||||
jobs.DataRetentionJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeDataRetention, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting data retention jobs"))
|
||||
}
|
||||
jobs.MessageExportJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeMessageExport, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting message export jobs"))
|
||||
}
|
||||
jobs.ElasticPostIndexingJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeElasticsearchPostIndexing, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post indexing jobs"))
|
||||
}
|
||||
jobs.ElasticPostAggregationJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeElasticsearchPostAggregation, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting ES post aggregation jobs"))
|
||||
}
|
||||
jobs.MigrationJobs, err = a.Srv().Store().Job().GetAllByTypePage(rctx, model.JobTypeMigrations, 0, numberOfJobsRuns)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "error while getting migration jobs"))
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(&jobs)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to marshal jobs list into yaml"))
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: "jobs.yaml",
|
||||
Body: b,
|
||||
}
|
||||
return fileData, rErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (a *App) getSupportPacketPermissionsInfo(_ request.CTX) (*model.FileData, error) {
|
||||
var (
|
||||
rErr *multierror.Error
|
||||
err error
|
||||
permissions model.SupportPacketPermissionInfo
|
||||
)
|
||||
|
||||
var allSchemes []*model.Scheme
|
||||
perPage := 100
|
||||
page := 0
|
||||
for {
|
||||
schemes, appErr := a.GetSchemesPage("", page, perPage)
|
||||
if appErr != nil {
|
||||
rErr = multierror.Append(errors.Wrap(appErr, "failed to get list of schemes"))
|
||||
break
|
||||
}
|
||||
|
||||
allSchemes = append(allSchemes, schemes...)
|
||||
if len(schemes) < perPage {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
for _, s := range allSchemes {
|
||||
s.Sanitize()
|
||||
}
|
||||
permissions.Schemes = allSchemes
|
||||
|
||||
roles, appErr := a.GetAllRoles()
|
||||
if appErr != nil {
|
||||
rErr = multierror.Append(errors.Wrap(appErr, "failed to get list of roles"))
|
||||
}
|
||||
|
||||
for _, r := range roles {
|
||||
r.Sanitize()
|
||||
}
|
||||
permissions.Roles = roles
|
||||
|
||||
b, err := yaml.Marshal(&permissions)
|
||||
if err != nil {
|
||||
rErr = multierror.Append(errors.Wrap(err, "failed to marshal permission info into yaml"))
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: "permissions.yaml",
|
||||
Body: b,
|
||||
}
|
||||
return fileData, rErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
func (a *App) getPluginsFile(_ request.CTX) (*model.FileData, error) {
|
||||
// Getting the plugins installed on the server, prettify it, and then add them to the file data array
|
||||
plugins, appErr := a.GetPlugins()
|
||||
if appErr != nil {
|
||||
return nil, errors.Wrap(appErr, "failed to get plugin list for Support Packet")
|
||||
}
|
||||
|
||||
var pluginList model.SupportPacketPluginList
|
||||
for _, p := range plugins.Active {
|
||||
pluginList.Enabled = append(pluginList.Enabled, p.Manifest)
|
||||
}
|
||||
for _, p := range plugins.Inactive {
|
||||
pluginList.Disabled = append(pluginList.Disabled, p.Manifest)
|
||||
}
|
||||
|
||||
pluginsPrettyJSON, err := json.MarshalIndent(pluginList, "", " ")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal plugin list into json")
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: "plugins.json",
|
||||
Body: pluginsPrettyJSON,
|
||||
}
|
||||
return fileData, nil
|
||||
}
|
||||
|
||||
func (a *App) getSupportPacketMetadata(_ request.CTX) (*model.FileData, error) {
|
||||
metadata, err := model.GeneratePacketMetadata(model.SupportPacketType, a.ServerId(), a.License(), nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to generate Packet metadata")
|
||||
}
|
||||
|
||||
b, err := yaml.Marshal(metadata)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal Packet metadata into yaml")
|
||||
}
|
||||
|
||||
fileData := &model.FileData{
|
||||
Filename: model.PacketMetadataFileName,
|
||||
Body: b,
|
||||
}
|
||||
return fileData, nil
|
||||
}
|
||||
|
||||
func (a *App) getSupportPacketDatabaseSchema(rctx request.CTX) (*model.FileData, error) {
|
||||
if *a.Config().SqlSettings.DriverName != model.DatabaseDriverPostgres {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
schemaInfo, err := a.Srv().Store().GetSchemaDefinition()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get schema definition")
|
||||
}
|
||||
|
||||
schemaDump, err := yaml.Marshal(schemaInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal schema into YAML")
|
||||
}
|
||||
|
||||
return &model.FileData{
|
||||
Filename: "database_schema.yaml",
|
||||
Body: schemaDump,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user