Additional Product APIs for Focalboard multi-product architecture (#20527)

* bump focalboard version; add services to product API

* add API to fetch logger

* import boards in same fashion as enterprise
This commit is contained in:
Doug Lauder 2022-06-23 07:55:50 -04:00 committed by GitHub
parent 4b5d56a8c2
commit f4dcffd8d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 99 additions and 50 deletions

3
.gitignore vendored
View file

@ -22,8 +22,9 @@ config/config.json
config/logging.json
/plugins
# Enterprise imports file
# Enterprise & products imports files
imports/imports.go
imports/boards_imports.go
# go.work file
go.work

View file

@ -38,6 +38,8 @@ ifeq ($(BUILD_NUMBER),)
BUILD_DATE := n/a
BUILD_NUMBER := dev
endif
# Enterprise
BUILD_ENTERPRISE_DIR ?= ../enterprise
BUILD_ENTERPRISE ?= true
BUILD_ENTERPRISE_READY = false
@ -56,6 +58,8 @@ else
BUILD_ENTERPRISE_READY = false
BUILD_TYPE_NAME = team
endif
# Webapp
BUILD_WEBAPP_DIR ?= ../mattermost-webapp
BUILD_CLIENT = false
BUILD_HASH_CLIENT = independent
@ -70,6 +74,21 @@ else
BUILD_CLIENT = false
endif
# Boards
BUILD_BOARDS_DIR ?= ../focalboard
BUILD_BOARDS ?= true
BUILD_HASH_BOARDS = none
ifneq ($(wildcard $(BUILD_BOARDS_DIR)/.),)
ifeq ($(BUILD_BOARDS),true)
BUILD_BOARDS = true
BUILD_HASH_BOARDS = $(shell cd $(BUILD_BOARDS_DIR) && git rev-parse HEAD)
else
BUILD_BOARDS = false
endif
else
BUILD_BOARDS = false
endif
# We need current user's UID for `run-haserver` so docker compose does not run server
# as root and mess up file permissions for devs. When running like this HOME will be blank
# and docker will add '/', so we need to set the go-build cache location or we'll get
@ -91,6 +110,8 @@ LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildDate=$(BUIL
LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildHash=$(BUILD_HASH)"
LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildHashEnterprise=$(BUILD_HASH_ENTERPRISE)"
LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildEnterpriseReady=$(BUILD_ENTERPRISE_READY)"
LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildHashBoards=$(BUILD_HASH_BOARDS)"
LDFLAGS += -X "github.com/mattermost/mattermost-server/v6/model.BuildBoards=$(BUILD_BOARDS)"
GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1)
GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
@ -156,6 +177,17 @@ else
ALL_PACKAGES=$(TE_PACKAGES)
endif
# Prepare optional Boards build.
BOARDS_PACKAGES=$(shell $(GO) list $(BUILD_BOARDS_DIR)/server/...)
ifeq ($(BUILD_BOARDS),true)
ALL_PACKAGES += $(BOARDS_PACKAGES)
IGNORE:=$(shell echo Boards build selected, preparing)
IGNORE:=$(shell rm -f imports/boards_imports.go)
IGNORE:=$(shell cp $(BUILD_BOARDS_DIR)/mattermost-plugin/product/imports/boards_imports.go imports/)
else
IGNORE:=$(shell rm -f imports/boards_imports.go)
endif
all: run ## Alias for 'run'.
-include config.override.mk
@ -276,7 +308,12 @@ golangci-lint: ## Run golangci-lint on codebase
$(GOBIN)/golangci-lint run ./...
ifeq ($(BUILD_ENTERPRISE_READY),true)
ifneq ($(MM_NO_ENTERPRISE_LINT),true)
$(GOBIN)/golangci-lint run ../enterprise/...
$(GOBIN)/golangci-lint run ../enterprise/...
endif
endif
ifeq ($(BUILD_BOARDS),true)
ifneq ($(MM_NO_BOARDS_LINT),true)
$(GOBIN)/golangci-lint run $(BUILD_BOARDS_DIR)/server/...
endif
endif
@ -361,10 +398,10 @@ ifeq ($(BUILD_ENTERPRISE_READY),true)
./scripts/prereq-check-enterprise.sh
endif
setup-go-work: export BUILD_ENTERPRISE_READY := $(BUILD_ENTERPRISE_READY)
setup-go-work: export BUILD_BOARDS := $(BUILD_BOARDS)
setup-go-work: ## Sets up your go.work file
ifeq ($(BUILD_ENTERPRISE_READY),true)
./scripts/setup_go_work.sh
endif
check-style: golangci-lint plugin-checker vet ## Runs style/lint checks
@ -396,6 +433,9 @@ gomodtidy:
@if [ -f "imports/imports.go" ]; then \
mv imports/imports.go imports/imports.go.orig; \
fi;
@if [ -f "imports/boards_imports.go" ]; then \
mv imports/boards_imports.go imports/boards_imports.go.orig; \
fi;
$(GO) mod tidy
@if [ "$$(diff go.mod go.mod.orig)" != "" -o "$$(diff go.sum go.sum.orig)" != "" ]; then \
echo "go.mod/go.sum was modified. \ndiff- $$(diff go.mod go.mod.orig) \n$$(diff go.sum go.sum.orig) \nRun \"go mod tidy\"."; \
@ -405,17 +445,25 @@ gomodtidy:
@if [ -f "imports/imports.go.orig" ]; then \
mv imports/imports.go.orig imports/imports.go; \
fi;
@if [ -f "imports/boards_imports.go.orig" ]; then \
mv imports/boards_imports.go.orig imports/boards_imports.go; \
fi;
@rm go.*.orig;
modules-tidy:
@if [ -f "imports/imports.go" ]; then \
mv imports/imports.go imports/imports.go.orig; \
fi;
@if [ -f "imports/boards_imports.go" ]; then \
mv imports/boards_imports.go imports/boards_imports.go.orig; \
fi;
-$(GO) mod tidy
@if [ -f "imports/imports.go.orig" ]; then \
mv imports/imports.go.orig imports/imports.go; \
fi;
@if [ -f "imports/boards_imports.go.orig" ]; then \
mv imports/boards_imports.go.orig imports/boards_imports.go; \
fi;
test-server-pre: check-prereqs-enterprise start-docker go-junit-report do-cover-file ## Runs tests.
ifeq ($(BUILD_ENTERPRISE_READY),true)

View file

@ -10,6 +10,8 @@ import (
"sync"
"sync/atomic"
"github.com/pkg/errors"
"github.com/mattermost/mattermost-server/v6/app/imaging"
"github.com/mattermost/mattermost-server/v6/app/request"
"github.com/mattermost/mattermost-server/v6/config"
@ -20,19 +22,8 @@ import (
"github.com/mattermost/mattermost-server/v6/services/imageproxy"
"github.com/mattermost/mattermost-server/v6/shared/filestore"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
"github.com/pkg/errors"
)
// configSvc is a consumer interface to work
// with any config related task with the server.
type configSvc interface {
Config() *model.Config
AddConfigListener(listener func(*model.Config, *model.Config)) string
RemoveConfigListener(id string)
UpdateConfig(f func(*model.Config))
SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError)
}
// licenseSvc is added to act as a starting point for future integrated products.
// It has the same signature and functionality with the license related APIs of the plugin-api.
type licenseSvc interface {
@ -49,7 +40,7 @@ type namer interface {
// Channels contains all channels related state.
type Channels struct {
srv *Server
cfgSvc configSvc
cfgSvc product.ConfigService
filestore filestore.FileBackend
licenseSvc licenseSvc
routerSvc *routerService
@ -135,7 +126,7 @@ func NewChannels(s *Server, services map[ServiceKey]interface{}) (*Channels, err
switch svcKey {
// Keep adding more services here
case ConfigKey:
cfgSvc, ok := svc.(configSvc)
cfgSvc, ok := svc.(product.ConfigService)
if !ok {
return nil, errors.New("Config service did not satisfy ConfigSvc interface")
}

View file

@ -6,8 +6,6 @@ package app
import (
"fmt"
"strings"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
type Product interface {
@ -80,18 +78,3 @@ func (s *Server) initializeProducts(
return nil
}
type logWrapper struct {
srv *Server
}
func (s *logWrapper) LogError(productID, msg string, keyValuePairs ...interface{}) {
s.srv.Log.Error(msg, mlog.String("product_id", productID), mlog.Map("key-value pairs", keyValuePairs))
}
func (s *logWrapper) LogWarn(productID, msg string, keyValuePairs ...interface{}) {
s.srv.Log.Warn(msg, mlog.String("product_id", productID), mlog.Map("key-value pairs", keyValuePairs))
}
func (s *logWrapper) LogDebug(productID, msg string, keyValuePairs ...interface{}) {
s.srv.Log.Debug(msg, mlog.String("product_id", productID), mlog.Map("key-value pairs", keyValuePairs))
}

View file

@ -399,9 +399,7 @@ func NewServer(options ...Option) (*Server, error) {
FilestoreKey: s.filestore,
ClusterKey: s.clusterWrapper,
UserKey: New(ServerConnector(s.Channels())),
LogKey: &logWrapper{
srv: s,
},
LogKey: s.GetLogger(),
}
// Step 8: Initialize products.

View file

@ -109,6 +109,8 @@ var BuildDate string
var BuildHash string
var BuildHashEnterprise string
var BuildEnterpriseReady string
var BuildHashBoards string
var BuildBoards string
var versionsWithoutHotFixes []string
func init() {

View file

@ -4,10 +4,14 @@
package product
import (
"io"
"github.com/gorilla/mux"
"github.com/mattermost/mattermost-server/v6/app/request"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/plugin"
"github.com/mattermost/mattermost-server/v6/shared/filestore"
)
// RouterService enables registering the product router to the server. After registering the
@ -95,11 +99,13 @@ type BotService interface {
EnsureBot(ctx *request.Context, productID string, bot *model.Bot) (string, error)
}
// LogService shall be registered via app.LogKey service key.
type LogService interface {
LogError(productID, msg string, keyValuePairs ...interface{})
LogWarn(productID, msg string, keyValuePairs ...interface{})
LogDebug(productID, msg string, keyValuePairs ...interface{})
// ConfigService shall be registered via app.ConfigKey service key.
type ConfigService interface {
Config() *model.Config
AddConfigListener(listener func(*model.Config, *model.Config)) string
RemoveConfigListener(id string)
UpdateConfig(f func(*model.Config))
SaveConfig(newCfg *model.Config, sendConfigChangeClusterMessage bool) (*model.Config, *model.Config, *model.AppError)
}
// Hooks is an interim solution for enabling plugin hooks on the multi-product architecture. After the
@ -116,3 +122,15 @@ type Hooks interface {
type HooksService interface {
RegisterHooks(productID string, hooks Hooks) error
}
// FilestoreService is the API for accessing the file store.
//
// The service shall be registered via app.FilestoreKey service key.
type FilestoreService interface {
Reader(path string) (filestore.ReadCloseSeeker, error)
FileExists(path string) (bool, error)
CopyFile(oldPath, newPath string) error
MoveFile(oldPath, newPath string) error
WriteFile(fr io.Reader, path string) (int64, error)
RemoveFile(path string) error
}

View file

@ -3,11 +3,18 @@
if [[ ! -f "go.work" ]] ;
then
echo "Creating a go.work file"
cat >go.work <<EOL
go 1.18
use ./
use ../enterprise
EOL
fi
txt="go 1.18\n\nuse ./\n"
if [ "$BUILD_ENTERPRISE_READY" == "true" ]
then
txt="${txt}use ../enterprise\n"
fi
if [ "$BUILD_BOARDS" == "true" ]
then
txt="${txt}use ../focalboard/server\nuse ../focalboard/mattermost-plugin\n"
fi
printf "$txt" > "go.work"
fi

View file

@ -37,6 +37,7 @@ type LoggerIFace interface {
Critical(string, ...Field)
Log(Level, string, ...Field)
LogM([]Level, string, ...Field)
With(fields ...Field) *Logger
}
// Type and function aliases from Logr to limit the spread of dependencies.