Fb1463 no cluster build (#2100)

* got single node working; refining error messaging and version info to follow

* better implementation that separates the build condition into etcd/enterprise_cluster.go and etcd/plg_cluster.go. go build will default to a clustering version and 'go build -tags plg' will build the non-clustering version

* added Makefile target for 'make plg'

* additional comments, CI/CD update

Co-authored-by: Kasey Rodgers <kaseyrodgers@Kaseys-MBP.attlocal.net>
This commit is contained in:
Kasey C. Rodgers 2022-06-09 12:32:46 -07:00 committed by GitHub
parent ff7900070c
commit 2ef39fdc9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 25 deletions

View file

@ -138,6 +138,24 @@ run go tests future:
tags:
- aws
run go tests future plg:
stage: test
allow_failure: true
image: golang:1.18
rules:
- if: '$CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "schedule" || $CI_PIPELINE_SOURCE == "web"'
retry: 1
script:
- echo "Running featurebase plg-specific unit tests..."
- PKG_LIST=$(go list ./... | grep -v internal/clustertests | paste -s -d, -)
- go test -tags=plg -timeout=30m -json -coverprofile=coverage-plg.out -covermode=atomic -coverpkg=${PKG_LIST} ./... | tee test-report-plg.out
artifacts:
paths:
- coverage-plg.out
- test-report-plg.out
tags:
- aws
upload to sonarcloud:
stage: integration
image: sonarsource/sonar-scanner-cli:4.6
@ -146,7 +164,7 @@ upload to sonarcloud:
rules:
- if: '$CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "schedule" || $CI_PIPELINE_SOURCE == "web"'
script:
- sonar-scanner -Dsonar.projectKey=molecula_featurebase -Dsonar.organization=molecula -Dsonar.sources=. -Dsonar.host.url=https://sonarcloud.io -Dsonar.go.coverage.reportPaths=coverage.out,results/coverage*.out -Dsonar.go.tests.reportPaths=test-report.out,results/report* -Dsonar.javascript.lcov.reportPaths=lattice/coverage/lcov.info
- sonar-scanner -Dsonar.projectKey=molecula_featurebase -Dsonar.organization=molecula -Dsonar.sources=. -Dsonar.host.url=https://sonarcloud.io -Dsonar.go.coverage.reportPaths=coverage-plg.out,results/coverage*.out -Dsonar.go.tests.reportPaths=test-report-plg.out,results/report* -Dsonar.javascript.lcov.reportPaths=lattice/coverage/lcov.info
needs:
- job: run go tests future
- job: run jest tests

View file

@ -168,6 +168,10 @@ authclustertests: vendor
install:
$(GO) install -tags='$(BUILD_TAGS)' -ldflags $(LDFLAGS) $(FLAGS) ./cmd/featurebase
# Install the single-node PLG version of FeatureBase
plg:
$(GO) install -tags='plg $(BUILD_TAGS)' -ldflags $(LDFLAGS) $(FLAGS) ./cmd/featurebase
install-bench:
$(GO) install -tags='$(BUILD_TAGS)' -ldflags $(LDFLAGS) $(FLAGS) ./cmd/pilosa-bench

View file

@ -8,6 +8,7 @@ import (
"fmt"
"log"
"net"
"os"
"path"
"sort"
"strings"
@ -16,6 +17,7 @@ import (
"github.com/molecula/featurebase/v3/disco"
"github.com/molecula/featurebase/v3/logger"
"github.com/molecula/featurebase/v3/monitor"
"github.com/molecula/featurebase/v3/topology"
"github.com/pkg/errors"
"go.etcd.io/etcd/api/v3/mvccpb"
@ -257,36 +259,48 @@ func (e *Etcd) retryClient(fn func(cli *clientv3.Client) error) (err error) {
return errors.Wrap(err, "exhausted all retries")
}
func parseOptions(opt Options) *embed.Config {
func (e *Etcd) parseOptions() *embed.Config {
cfg := embed.NewConfig()
cfg.LogLevel = "error"
cfg.Logger = "zap"
cfg.Name = opt.Name
cfg.Dir = opt.Dir
cfg.InitialClusterToken = opt.ClusterName
cfg.LCUrls = types.MustNewURLs([]string{opt.LClientURL})
cfg.UnsafeNoFsync = opt.UnsafeNoFsync
if opt.AClientURL != "" {
cfg.ACUrls = types.MustNewURLs([]string{opt.AClientURL})
cfg.Name = e.options.Name
cfg.Dir = e.options.Dir
cfg.InitialClusterToken = e.options.ClusterName
cfg.LCUrls = types.MustNewURLs([]string{e.options.LClientURL})
cfg.UnsafeNoFsync = e.options.UnsafeNoFsync
if e.options.AClientURL != "" {
cfg.ACUrls = types.MustNewURLs([]string{e.options.AClientURL})
} else {
cfg.ACUrls = cfg.LCUrls
}
cfg.LPUrls = types.MustNewURLs([]string{opt.LPeerURL})
if opt.APeerURL != "" {
cfg.APUrls = types.MustNewURLs([]string{opt.APeerURL})
cfg.LPUrls = types.MustNewURLs([]string{e.options.LPeerURL})
if e.options.APeerURL != "" {
cfg.APUrls = types.MustNewURLs([]string{e.options.APeerURL})
} else {
cfg.APUrls = cfg.LPUrls
}
if opt.InitCluster != "" {
cfg.InitialCluster = opt.InitCluster
if e.options.InitCluster != "" {
// Checks if FB is running the single-node free version or the multi-node
// enterprise version. Sentry.io is enabled on single-node.
if AllowCluster() == false {
monitor.InitErrorMonitor()
e.logger.Infof("Initializing Monitor: Capturing usage metrics")
//check for multiple nodes in the cluster and error if present
nodes := strings.Split(e.options.InitCluster, ",")
if len(nodes) > 1 {
e.logger.Warnf("Multiple cluster nodes detected - this version of FeatureBase only supports single node. %+v", e.options.InitCluster)
os.Exit(1)
}
}
cfg.InitialCluster = e.options.InitCluster
cfg.ClusterState = embed.ClusterStateFlagNew
} else {
cfg.InitialCluster = cfg.Name + "=" + opt.APeerURL
cfg.InitialCluster = cfg.Name + "=" + e.options.APeerURL
}
if opt.ClusterURL != "" {
if e.options.ClusterURL != "" {
cfg.ClusterState = embed.ClusterStateFlagExisting
cli, err := clientv3.NewFromURL(opt.ClusterURL)
cli, err := clientv3.NewFromURL(e.options.ClusterURL)
if err != nil {
panic(err)
}
@ -294,25 +308,26 @@ func parseOptions(opt Options) *embed.Config {
log.Println("Cluster Members:")
mIDs, mNames, mURLs := memberList(cli)
for i, id := range mIDs {
log.Printf("\tid: %d, name: %s, url: %s\n", id, mNames[i], mURLs[i])
cfg.InitialCluster += "," + mNames[i] + "=" + mURLs[i]
}
log.Println("Joining Cluster:")
id, name := memberAdd(cli, opt.APeerURL)
id, name := memberAdd(cli, e.options.APeerURL)
log.Printf("\tid: %d, name: %s\n", id, name)
}
// can only use tls if not using pre-configured listeners
cfg.ClientTLSInfo = transport.TLSInfo{
TrustedCAFile: opt.TrustedCAFile,
CertFile: opt.ClientCertFile,
KeyFile: opt.ClientKeyFile,
TrustedCAFile: e.options.TrustedCAFile,
CertFile: e.options.ClientCertFile,
KeyFile: e.options.ClientKeyFile,
}
cfg.PeerTLSInfo = transport.TLSInfo{
TrustedCAFile: opt.TrustedCAFile,
CertFile: opt.PeerCertFile,
KeyFile: opt.PeerKeyFile,
TrustedCAFile: e.options.TrustedCAFile,
CertFile: e.options.PeerCertFile,
KeyFile: e.options.PeerKeyFile,
}
return cfg
@ -320,7 +335,7 @@ func parseOptions(opt Options) *embed.Config {
// Start starts etcd and hearbeat
func (e *Etcd) Start(ctx context.Context) (_ disco.InitialClusterState, err error) {
opts := parseOptions(e.options)
opts := e.parseOptions()
state := disco.InitialClusterState(opts.ClusterState)
e.e, err = embed.StartEtcd(opts)

View file

@ -0,0 +1,11 @@
//go:build !plg
// +build !plg
// Copyright 2022 Molecula Corp. All rights reserved.
package etcd
// allows us to conditionally build an enterprise version of
// FB that does cluster, in contrast to the PLG version.
func AllowCluster() bool {
return true
}

11
etcd/plg_cluster.go Normal file
View file

@ -0,0 +1,11 @@
//go:build plg
// +build plg
// Copyright 2022 Molecula Corp. All rights reserved.
package etcd
// allows us to conditionally build a version of FB that does not
// cluster, to make a demo available for our Product Led Growth.
func AllowCluster() bool {
return false
}