Configurable dev environment (#14869)

* Configurable dev environment

* Add a bit of documentation

* fixing gofmt

* A bit more doc

* Using  variable

* Adding license header

* Moving LDAP_DATA variable to the default-config.mk file

* Adding another docker-compose for the makefile to not brake anybody workflow

* Moving dejavu to the config

* Fixing docker-compose.makefile.yaml for dejavu

* Adding keycloak support to the dev environment

* Address PR review comments

* Removing minio from default docker images

* Changing the default version of mysql to the oldest supported (5.6)

* Change the restart option to no for the dev environment

* Fixing restart option

* Reverting unneded changes

* Restoring 5.7 to check if test passes

* Going back to 5.6 mysql image

* Fixing tests on mysql 5.6

* Skipping flaky test

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
Jesús Espino
2020-07-13 22:29:39 +02:00
committed by GitHub
parent 6ad5ef2b43
commit e980dd7bd3
13 changed files with 2246 additions and 17 deletions

1
.gitignore vendored
View File

@@ -110,3 +110,4 @@ client
__debug_bin
report.xml
go.*.orig
config.override.mk

View File

@@ -9,7 +9,6 @@ else
endif
IS_CI ?= false
MM_NO_DOCKER ?= false
# Build Flags
BUILD_NUMBER ?= $(BUILD_NUMBER:)
BUILD_DATE = $(shell date -u)
@@ -23,7 +22,6 @@ BUILD_ENTERPRISE ?= true
BUILD_ENTERPRISE_READY = false
BUILD_TYPE_NAME = team
BUILD_HASH_ENTERPRISE = none
LDAP_DATA ?= test
ifneq ($(wildcard $(BUILD_ENTERPRISE_DIR)/.),)
ifeq ($(BUILD_ENTERPRISE),true)
BUILD_ENTERPRISE_READY = true
@@ -97,7 +95,6 @@ PLUGIN_PACKAGES += mattermost-plugin-jira-v2.3.2
PLUGIN_PACKAGES += mattermost-plugin-gitlab-v1.1.0
PLUGIN_PACKAGES += mattermost-plugin-jenkins-v1.0.0
# Prepares the enterprise build if exists. The IGNORE stuff is a hack to get the Makefile to execute the commands outside a target
ifeq ($(BUILD_ENTERPRISE_READY),true)
IGNORE:=$(shell echo Enterprise build selected, preparing)
@@ -122,8 +119,15 @@ MMCTL_REL_TO_DOWNLOAD = $(shell scripts/get_latest_release.sh 'mattermost/mmctl'
all: run ## Alias for 'run'.
-include config.override.mk
include config.mk
include build/*.mk
RUN_IN_BACKGROUND ?=
ifeq ($(RUN_SERVER_IN_BACKGROUND),true)
RUN_IN_BACKGROUND := &
endif
start-docker: ## Starts the docker containers for local development.
ifneq ($(IS_CI),false)
@echo CI Build: skipping docker start
@@ -132,8 +136,10 @@ else ifeq ($(MM_NO_DOCKER),true)
else
@echo Starting docker containers
docker-compose run --rm start_dependencies
cat tests/${LDAP_DATA}-data.ldif | docker-compose exec -T openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest || true';
$(GO) run ./build/docker-compose-generator/main.go $(ENABLED_DOCKER_SERVICES) | docker-compose -f docker-compose.makefile.yml -f /dev/stdin run --rm start_dependencies
ifneq (,$(findstring openldap,$(ENABLED_DOCKER_SERVICES)))
cat tests/${LDAP_DATA}-data.ldif | docker-compose -f docker-compose.makefile.yml exec -T openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest || true';
endif
endif
stop-docker: ## Stops the docker containers for local development.
@@ -368,7 +374,7 @@ run-server: prepackaged-binaries validate-go-version start-docker ## Starts the
mkdir -p $(BUILD_WEBAPP_DIR)/dist/files
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) --disableconfigwatch 2>&1 | \
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) logs --logrus &
$(GO) run $(GOFLAGS) -ldflags '$(LDFLAGS)' $(PLATFORM_FILES) logs --logrus $(RUN_IN_BACKGROUND)
debug-server: start-docker ## Compile and start server using delve.
mkdir -p $(BUILD_WEBAPP_DIR)/dist/files
@@ -545,3 +551,6 @@ endif
## Help documentatin à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
help:
@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' ./Makefile | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
@echo
@echo You can modify the default settings for this Makefile creating a file config.mk based on the default-config.mk
@echo

View File

@@ -0,0 +1,60 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package main
import (
"fmt"
"os"
"strings"
"gopkg.in/yaml.v2"
)
type DockerCompose struct {
Version string `yaml:"version"`
Services map[string]*Container `yaml:"services"`
}
type Container struct {
Command string `yaml:"command,omitempty"`
Image string `yaml:"image,omitempty"`
Network []string `yaml:"networks,omitempty"`
DependsOn []string `yaml:"depends_on,omitempty"`
}
func main() {
validServices := map[string]int{
"mysql": 3306,
"postgres": 5432,
"minio": 9000,
"inbucket": 10080,
"openldap": 389,
"elasticsearch": 9200,
"dejavu": 1358,
"keycloak": 8080,
}
command := []string{}
for _, arg := range os.Args[1:] {
port, ok := validServices[arg]
if !ok {
panic(fmt.Sprintf("Unknown service %s", arg))
}
command = append(command, fmt.Sprintf("%s:%d", arg, port))
}
var dockerCompose DockerCompose
dockerCompose.Version = "2.4"
dockerCompose.Services = map[string]*Container{}
dockerCompose.Services["start_dependencies"] = &Container{
Image: "mattermost/mattermost-wait-for-dep:latest",
Network: []string{"mm-test"},
DependsOn: os.Args[1:],
Command: strings.Join(command, " "),
}
resultData, err := yaml.Marshal(dockerCompose)
if err != nil {
panic(fmt.Sprintf("Unable to serialize the docker-compose file: %s.", err.Error()))
}
fmt.Println(string(resultData))
}

View File

@@ -1,7 +1,7 @@
version: '2.4'
services:
mysql:
image: "mysql:5.7"
image: "mysql:5.6"
restart: always
networks:
- mm-test
@@ -60,3 +60,19 @@ services:
http.cors.allow-credentials: "true"
transport.host: "127.0.0.1"
ES_JAVA_OPTS: "-Xms512m -Xmx512m"
dejavu:
image: "appbaseio/dejavu:3.4.2"
networks:
- mm-test
keycloak:
image: "jboss/keycloak:10.0.2"
restart: always
environment:
KEYCLOAK_USER: mmuser
KEYCLOAK_PASSWORD: mostest
DB_VENDOR: h2
KEYCLOAK_IMPORT: /setup/realm.json
networks:
- mm-test
volumes:
- "./docker/keycloak:/setup"

View File

@@ -1,6 +0,0 @@
version: '2.4'
services:
dejavu:
image: "appbaseio/dejavu:3.4.2"
networks:
- mm-test

View File

@@ -28,6 +28,14 @@ services:
extends:
file: docker-compose.common.yml
service: elasticsearch
dejavu:
extends:
file: docker-compose.common.yml
service: dejavu
keycloak:
extends:
file: docker-compose.common.yml
service: keycloak
start_dependencies:
image: mattermost/mattermost-wait-for-dep:latest

View File

@@ -0,0 +1,58 @@
To use this keycloak image, we suggest you to use this configuration settings:
- Enable Login With SAML 2.0: `true`
- Enable Synchronizing SAML Accounts With AD/LDAP: `true`
- Override SAML bind data with AD/LDAP information: `false`
- Identity Provider Metadata URL: empty string
- SAML SSO URL: `http://localhost:8484/auth/realms/mattermost/protocol/saml`
- Identity Provider Issuer URL: h`ttp://localhost:8065/login/sso/SAML`
- Identity Provider Public Certificate: The file `keycloak_cert.pem` in this same directory
- Verify Signature: `true`
- Service Provider Login URL: `http://localhost:8065/login/sso/saml`
- Enable Encryption: `false`
- Sign Request: `false`
- Email Attribute: `email`
- Username Attribute: `username`
- Id Attribute: `id`
- First Name Attribute: `firstName`
- Last Name Attribute: `lastName`
or overwrite your SamleSettings section with this settings in your config.json file (if you are not using
database configuration) and restart the server:
```json
"SamlSettings": {
"Enable": true,
"EnableSyncWithLdap": true,
"EnableSyncWithLdapIncludeAuth": false,
"Verify": true,
"Encrypt": false,
"SignRequest": false,
"IdpUrl": "http://localhost:8484/auth/realms/mattermost/protocol/saml",
"IdpDescriptorUrl": "http://localhost:8065/login/sso/saml",
"IdpMetadataUrl": "",
"AssertionConsumerServiceURL": "http://localhost:8065/login/sso/saml",
"SignatureAlgorithm": "RSAwithSHA1",
"CanonicalAlgorithm": "Canonical1.0",
"ScopingIDPProviderId": "",
"ScopingIDPName": "",
"IdpCertificateFile": "saml-idp.crt",
"PublicCertificateFile": "",
"PrivateKeyFile": "",
"IdAttribute": "id",
"GuestAttribute": "",
"EnableAdminAttribute": false,
"AdminAttribute": "",
"FirstNameAttribute": "firstName",
"LastNameAttribute": "lastName",
"EmailAttribute": "email",
"UsernameAttribute": "username",
"NicknameAttribute": "",
"LocaleAttribute": "",
"PositionAttribute": "",
"LoginButtonText": "SAML",
"LoginButtonColor": "#34a28b",
"LoginButtonBorderColor": "#2389D7",
"LoginButtonTextColor": "#ffffff"
},
```

View File

@@ -0,0 +1,3 @@
-----BEGIN CERTIFICATE-----
MIICmzCCAYMCBgFlZqKaDTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMTgwODIzMTE1MjM2WhcNMjgwODIzMTE1NDE2WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWfMf7KfTiwF1cyBLDJXegQFgi9HqwKZaTA4GFhSBTcwQyNrv8hkv8q7h8Z6ZoVavhMqKnbcXHln8s3CEQ0/z1UrLL3dEfTH0UMkkAEjPxei0iw0CTakawjkxmbbTXiglnFWv63nrV+PE5srXmm8yymfL4gJMtL7SlfPpJ+YHUNdwhlovxUUmGvBk4M82T1Ht2Hy3DPYF21a2JN2PF7hKRa/vhcAWSNaRnSrj1vGJml7YsNdmh/MIdGaxT6Rdx7zkO+4VcooT4CuQ12aLyV5eKOD/558BANth2eWIsXWhh/VFB1Zq1+dYyKLyjvo5fs/itdw31M66s/H/WkRIrTn/TAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJRpSNuBBmIELqIf7jF5I01mGiPMEkiqxENK1JH6iy8VOVljdM9tC1I1Dv6skx/0wCSX8cT32Dza0zJZN6Rvzt23DTh4yUWBosIOfmmL2uE7aeVVMm+jVzmynUVBTKfye3ki/ivBGJB8vsM1JuN/N4KE8WoH7iKMovETUb3cM44NfmMyhYyMWVrv02j3Pl6D4GadafawBPDQZGttotPo9kzYPpsQP6qYqtoZgSnX1BqOacPU+vKr8OIZM579hDkpDw0PvnCFvQeVlPseRTRv9ZwvbAksw6DwstJWp4eNd9nol8Apog+k0uzj+CGYXfWNWbz3LZ4/9BXhbwGxuYo4jUk=
-----END CERTIFICATE-----

File diff suppressed because it is too large Load Diff

24
config.mk Normal file
View File

@@ -0,0 +1,24 @@
# Do not modify this file, if you want to configure your own environment copy
# this file in config.override.mk and modify that file, or defining environment
# variables using the same names found here.
# Enable services to be run in docker.
#
# Possible options: mysql, postgres, minio, inbucket, openldap, dejavu,
# keycloak and elasticsearch
#
# Must be space spearated names.
#
# Example: mysql postgres elasticsearch
ENABLED_DOCKER_SERVICES ?= mysql postgres inbucket
# Disable entirely the use of docker
MM_NO_DOCKER ?= false
# Run the server in the background
RUN_SERVER_IN_BACKGROUND ?= true
# Data loaded by default in openldap when container starts.
#
# Posible options: test or qa
LDAP_DATA ?= test

View File

@@ -0,0 +1,79 @@
version: '2.4'
services:
mysql:
restart: 'no'
container_name: mattermost-mysql
ports:
- "3306:3306"
extends:
file: build/docker-compose.common.yml
service: mysql
postgres:
restart: 'no'
container_name: mattermost-postgres
ports:
- "5432:5432"
extends:
file: build/docker-compose.common.yml
service: postgres
minio:
restart: 'no'
container_name: mattermost-minio
ports:
- "9000:9000"
extends:
file: build/docker-compose.common.yml
service: minio
inbucket:
restart: 'no'
container_name: mattermost-inbucket
ports:
- "10025:10025"
- "10080:10080"
- "10110:10110"
extends:
file: build/docker-compose.common.yml
service: inbucket
openldap:
restart: 'no'
container_name: mattermost-openldap
ports:
- "389:389"
- "636:636"
extends:
file: build/docker-compose.common.yml
service: openldap
elasticsearch:
restart: 'no'
container_name: mattermost-elasticsearch
ports:
- "9200:9200"
- "9300:9300"
extends:
file: build/docker-compose.common.yml
service: elasticsearch
dejavu:
restart: 'no'
container_name: mattermost-dejavu
ports:
- "1358:1358"
extends:
file: build/docker-compose.common.yml
service: dejavu
keycloak:
restart: 'no'
container_name: mattermost-saml
ports:
- "8484:8080"
extends:
file: build/docker-compose.common.yml
service: keycloak
networks:
mm-test:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.254.0/24
ip_range: 192.168.254.0/24

View File

@@ -51,8 +51,15 @@ services:
ports:
- "1358:1358"
extends:
file: build/docker-compose.optional.yml
file: build/docker-compose.common.yml
service: dejavu
keycloak:
container_name: mattermost-saml
ports:
- "8484:8080"
extends:
file: build/docker-compose.common.yml
service: keycloak
start_dependencies:
image: mattermost/mattermost-wait-for-dep:latest

View File

@@ -24,6 +24,7 @@ import (
type SqlSupplier interface {
GetMaster() *gorp.DbMap
DriverName() string
}
func cleanupChannels(t *testing.T, ss store.Store) {
@@ -77,8 +78,8 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlSupplier) {
t.Run("GetMemberCount", func(t *testing.T) { testGetMemberCount(t, ss) })
t.Run("GetMemberCountsByGroup", func(t *testing.T) { testGetMemberCountsByGroup(t, ss) })
t.Run("GetGuestCount", func(t *testing.T) { testGetGuestCount(t, ss) })
t.Run("SearchInTeam", func(t *testing.T) { testChannelStoreSearchInTeam(t, ss, s) })
t.Run("SearchMore", func(t *testing.T) { testChannelStoreSearchMore(t, ss) })
t.Run("SearchInTeam", func(t *testing.T) { testChannelStoreSearchInTeam(t, ss) })
t.Run("SearchForUserInTeam", func(t *testing.T) { testChannelStoreSearchForUserInTeam(t, ss) })
t.Run("SearchAllChannels", func(t *testing.T) { testChannelStoreSearchAllChannels(t, ss) })
t.Run("GetMembersByIds", func(t *testing.T) { testChannelStoreGetMembersByIds(t, ss) })
@@ -4886,7 +4887,7 @@ func (s ByChannelDisplayName) Less(i, j int) bool {
return s[i].Id < s[j].Id
}
func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
func testChannelStoreSearchInTeam(t *testing.T, ss store.Store, s SqlSupplier) {
teamId := model.NewId()
otherTeamId := model.NewId()
@@ -5062,7 +5063,10 @@ func testChannelStoreSearchInTeam(t *testing.T, ss store.Store) {
"SearchInTeam": ss.Channel().SearchInTeam,
} {
for _, testCase := range testCases {
t.Run(testCase.Description, func(t *testing.T) {
t.Run(name+"/"+testCase.Description, func(t *testing.T) {
if name == "AutocompleteInTeam" && testCase.Description == "empty string" && s.DriverName() == model.DATABASE_DRIVER_MYSQL {
t.Skip("Skip test for MySQL. TODO: Understand why this test fails in mysql 5.6 in the CI")
}
channels, err := search(testCase.TeamId, testCase.Term, testCase.IncludeDeleted)
require.Nil(t, err)