summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2022-11-14 16:31:25 +0100
committerGitHub <noreply@github.com>2022-11-14 16:31:25 +0100
commit3da689318a80cd3da2c37f63c681f35a887d7911 (patch)
treeef6b19f9ec1a36828e7c085de609b7ea216cfdff
parentb10473ed6803e0bbd0aec7e1e90c7238153dc5c5 (diff)
parent754fe3a358eb4e83f632432324246863a2f4b7ba (diff)
Merge pull request #24852 from vespa-engine/arnej/use-common-container-base
Arnej/use common container base
-rw-r--r--client/go/jvm/application_container.go45
-rw-r--r--client/go/jvm/container.go51
-rw-r--r--client/go/jvm/env.go2
-rw-r--r--client/go/jvm/options.go25
-rw-r--r--client/go/jvm/run.go29
-rw-r--r--client/go/jvm/standalone_container.go42
-rw-r--r--client/go/prog/spec_env.go35
-rw-r--r--client/go/trace/trace.go19
8 files changed, 147 insertions, 101 deletions
diff --git a/client/go/jvm/application_container.go b/client/go/jvm/application_container.go
index 8470fbf2c13..2387ad66269 100644
--- a/client/go/jvm/application_container.go
+++ b/client/go/jvm/application_container.go
@@ -6,8 +6,6 @@ package jvm
import (
"fmt"
"os"
- "strconv"
- "strings"
"github.com/vespa-engine/vespa/client/go/defaults"
"github.com/vespa-engine/vespa/client/go/trace"
@@ -19,9 +17,7 @@ const (
)
type ApplicationContainer struct {
- configId string
- serviceName string
- jvmArgs *Options
+ containerBase
}
func (a *ApplicationContainer) ArgForMain() string {
@@ -29,14 +25,6 @@ func (a *ApplicationContainer) ArgForMain() string {
return fmt.Sprintf("file:%s/%s", dir, JAR_FOR_APPLICATION_CONTAINER)
}
-func (a *ApplicationContainer) ServiceName() string {
- return a.serviceName
-}
-
-func (a *ApplicationContainer) ConfigId() string {
- return a.configId
-}
-
func (a *ApplicationContainer) Discriminator() string {
cfgId := a.ConfigId()
if cfgId != "" {
@@ -71,7 +59,6 @@ func (a *ApplicationContainer) addJdiscProperties() {
opts.AddOption("-Djdisc.config.file=" + propsFile)
opts.AddOption("-Djdisc.cache.path=" + bCacheDir)
opts.AddOption("-Djdisc.logger.tag=" + cfgId)
-
}
func validPercentage(val int) bool {
@@ -132,15 +119,15 @@ func (a *ApplicationContainer) configureMemory(qc *QrStartConfig) {
func (a *ApplicationContainer) configureGC(qc *QrStartConfig) {
if extra := qc.Jvm.Gcopts; extra != "" {
- a.jvmArgs.AddJvmArgsFromString(extra)
+ a.JvmOptions().AddJvmArgsFromString(extra)
}
if qc.Jvm.Verbosegc {
- a.jvmArgs.AddOption("-Xlog:gc")
+ a.JvmOptions().AddOption("-Xlog:gc")
}
}
func (a *ApplicationContainer) configureClasspath(qc *QrStartConfig) {
- opts := a.jvmArgs
+ opts := a.JvmOptions()
if cp := qc.Jdisc.ClasspathExtra; cp != "" {
opts.classPath = append(opts.classPath, cp)
}
@@ -149,29 +136,13 @@ func (a *ApplicationContainer) configureClasspath(qc *QrStartConfig) {
func (a *ApplicationContainer) configureCPU(qc *QrStartConfig) {
cnt := qc.Jvm.AvailableProcessors
if cnt > 0 {
- trace.Trace("using", cnt, "from qr-start config")
- } else {
- out, err := util.BackTicksForwardStderr.Run("nproc", "--all")
- if err != nil {
- trace.Trace("failed nproc:", err)
- } else {
- cnt, err = strconv.Atoi(strings.TrimSpace(out))
- if err != nil {
- trace.Trace("bad nproc output:", strings.TrimSpace(out))
- cnt = 0
- } else {
- trace.Trace("using", cnt, "from nproc --all")
- }
- }
- }
- if cnt > 0 {
- num := strconv.Itoa(cnt)
- a.jvmArgs.AddOption("-XX:ActiveProcessorCount=" + num)
+ trace.Trace("CpuCount: using", cnt, "from qr-start config")
}
+ a.JvmOptions().ConfigureCpuCount(cnt)
}
-func (a *ApplicationContainer) addJvmArgs(opts *Options) {
- a.jvmArgs = opts
+func (a *ApplicationContainer) configureOptions() {
+ opts := a.JvmOptions()
opts.AddOption("-Dconfig.id=" + a.ConfigId())
if env := os.Getenv(VESPA_CONTAINER_JVMARGS); env != "" {
opts.AddJvmArgsFromString(env)
diff --git a/client/go/jvm/container.go b/client/go/jvm/container.go
index a07ba684a03..384384da137 100644
--- a/client/go/jvm/container.go
+++ b/client/go/jvm/container.go
@@ -3,9 +3,60 @@
package jvm
+import (
+ "fmt"
+ "strings"
+
+ "github.com/vespa-engine/vespa/client/go/prog"
+ "github.com/vespa-engine/vespa/client/go/trace"
+ "github.com/vespa-engine/vespa/client/go/util"
+)
+
type Container interface {
ServiceName() string
ConfigId() string
ArgForMain() string
+ JvmOptions() *Options
Exec()
}
+
+type containerBase struct {
+ configId string
+ serviceName string
+ jvmArgs *Options
+}
+
+func (cb *containerBase) ServiceName() string {
+ return cb.serviceName
+}
+
+func (cb *containerBase) JvmOptions() *Options {
+ return cb.jvmArgs
+}
+
+func (cb *containerBase) ConfigId() string {
+ return cb.configId
+}
+
+func readableEnv(env map[string]string) string {
+ var buf strings.Builder
+ for k, v := range env {
+ fmt.Fprintf(&buf, " %s=%s", k, v)
+ }
+ return buf.String()
+}
+
+func (cb *containerBase) Exec() {
+ argv := make([]string, 0, 100)
+ argv = append(argv, "java")
+ for _, x := range cb.JvmOptions().Args() {
+ argv = append(argv, x)
+ }
+ p := prog.NewSpec(argv)
+ p.ConfigureNumaCtl()
+ cb.exportEnvSettings(p)
+ trace.Info("starting container; env:", readableEnv(p.Env))
+ trace.Info("starting container; exec:", argv)
+ err := p.Run()
+ util.JustExitWith(err)
+}
diff --git a/client/go/jvm/env.go b/client/go/jvm/env.go
index 761c4ac5f9b..3db0cfd17b4 100644
--- a/client/go/jvm/env.go
+++ b/client/go/jvm/env.go
@@ -26,7 +26,7 @@ const (
MALLOC_ARENA_MAX = util.ENV_MALLOC_ARENA_MAX
)
-func exportEnvSettings(c Container, ps *prog.Spec) {
+func (c *containerBase) exportEnvSettings(ps *prog.Spec) {
vespaHome := defaults.VespaHome()
vlt := fmt.Sprintf("file:%s/logs/vespa/vespa.log", vespaHome)
lcd := fmt.Sprintf("%s/var/db/vespa/logcontrol", vespaHome)
diff --git a/client/go/jvm/options.go b/client/go/jvm/options.go
index a6800150d84..dae66690966 100644
--- a/client/go/jvm/options.go
+++ b/client/go/jvm/options.go
@@ -5,6 +5,7 @@ package jvm
import (
"fmt"
+ "strconv"
"strings"
"github.com/vespa-engine/vespa/client/go/defaults"
@@ -22,7 +23,7 @@ type Options struct {
fixSpec util.FixSpec
}
-func NewOptions(c Container) Options {
+func NewOptions(c Container) *Options {
vespaUid, vespaGid := vespa.FindVespaUidAndGid()
fixSpec := util.FixSpec{
UserId: vespaUid,
@@ -30,7 +31,7 @@ func NewOptions(c Container) Options {
DirMode: 0755,
FileMode: 0644,
}
- return Options{
+ return &Options{
container: c,
classPath: make([]string, 0, 10),
jvmArgs: make([]string, 0, 100),
@@ -75,3 +76,23 @@ func (opts *Options) AddJvmArgsFromString(args string) {
opts.AppendOption(x)
}
}
+
+func (opts *Options) ConfigureCpuCount(cnt int) {
+ if cnt <= 0 {
+ out, err := util.BackTicksForwardStderr.Run("nproc", "--all")
+ if err != nil {
+ trace.Trace("failed nproc:", err)
+ } else {
+ cnt, err = strconv.Atoi(strings.TrimSpace(out))
+ if err != nil {
+ trace.Trace("bad nproc output:", strings.TrimSpace(out))
+ cnt = 0
+ } else {
+ trace.Trace("CpuCount: using", cnt, "from nproc --all")
+ }
+ }
+ }
+ if cnt > 0 {
+ opts.AddOption(fmt.Sprintf("-XX:ActiveProcessorCount=%d", cnt))
+ }
+}
diff --git a/client/go/jvm/run.go b/client/go/jvm/run.go
index fad72376d6a..01111e8a1a4 100644
--- a/client/go/jvm/run.go
+++ b/client/go/jvm/run.go
@@ -6,7 +6,6 @@ package jvm
import (
"os"
- "github.com/vespa-engine/vespa/client/go/prog"
"github.com/vespa-engine/vespa/client/go/trace"
"github.com/vespa-engine/vespa/client/go/util"
)
@@ -25,29 +24,13 @@ func RunApplicationContainer(extraArgs []string) int {
}
func NewApplicationContainer(extraArgs []string) Container {
- configId := os.Getenv(util.ENV_CONFIG_ID)
- serviceName := os.Getenv(util.ENV_SERVICE_NAME)
- a := ApplicationContainer{
- configId: configId,
- serviceName: serviceName,
- }
- opts := NewOptions(&a)
- a.addJvmArgs(&opts)
+ var a ApplicationContainer
+ a.configId = os.Getenv(util.ENV_CONFIG_ID)
+ a.serviceName = os.Getenv(util.ENV_SERVICE_NAME)
+ a.jvmArgs = NewOptions(&a)
+ a.configureOptions()
for _, x := range extraArgs {
- opts.AddOption(x)
+ a.JvmOptions().AddOption(x)
}
return &a
}
-
-func (a *ApplicationContainer) Exec() {
- argv := make([]string, 0, 100)
- argv = append(argv, "java")
- for _, x := range a.jvmArgs.Args() {
- argv = append(argv, x)
- }
- p := prog.NewSpec(argv)
- p.ConfigureNumaCtl()
- exportEnvSettings(a, p)
- err := p.Run()
- util.JustExitWith(err)
-}
diff --git a/client/go/jvm/standalone_container.go b/client/go/jvm/standalone_container.go
index 36c56c09b23..a2181ed7c3e 100644
--- a/client/go/jvm/standalone_container.go
+++ b/client/go/jvm/standalone_container.go
@@ -5,8 +5,11 @@ package jvm
import (
"fmt"
+ "os"
"github.com/vespa-engine/vespa/client/go/defaults"
+ "github.com/vespa-engine/vespa/client/go/trace"
+ "github.com/vespa-engine/vespa/client/go/util"
)
const (
@@ -14,7 +17,7 @@ const (
)
type StandaloneContainer struct {
- serviceName string
+ containerBase
}
func (a *StandaloneContainer) ArgForMain() string {
@@ -29,11 +32,14 @@ func (a *StandaloneContainer) ConfigId() string {
return ""
}
-func (a *StandaloneContainer) addJvmArgs(opts *Options) {
+func (a *StandaloneContainer) configureOptions() {
+ opts := a.jvmArgs
+ opts.ConfigureCpuCount(0)
opts.AddCommonXX()
opts.AddOption("-XX:-OmitStackTraceInFastThrow")
opts.AddCommonOpens()
opts.AddCommonJdkProperties()
+ a.addJdiscProperties()
svcName := a.ServiceName()
if svcName == "configserver" {
RemoveStaleZkLocks(a)
@@ -41,16 +47,34 @@ func (a *StandaloneContainer) addJvmArgs(opts *Options) {
zkLogFile := fmt.Sprintf("%s/zookeeper.%s", logsDir, svcName)
opts.AddOption("-Dzookeeper_log_file_prefix=" + zkLogFile)
}
- panic("not finished yet")
}
-func (a *StandaloneContainer) Exec() {
- panic("not implemented yet")
+func NewStandaloneContainer(svcName string) Container {
+ var a StandaloneContainer
+ a.serviceName = svcName
+ a.jvmArgs = NewOptions(&a)
+ a.configureOptions()
+ return &a
}
-func NewStandaloneContainer(svcName string) Container {
- a := StandaloneContainer{
- serviceName: svcName,
+func (a *StandaloneContainer) addJdiscProperties() {
+ opts := a.JvmOptions()
+ opts.AddCommonJdiscProperties()
+ containerParentDir := defaults.UnderVespaHome("var/jdisc_container")
+ bCacheParentDir := defaults.UnderVespaHome("var/vespa/bundlecache")
+ svcName := a.ServiceName()
+ bCacheDir := fmt.Sprintf("%s/%s", bCacheParentDir, svcName)
+ propsFile := fmt.Sprintf("%s/%s.properties", containerParentDir, svcName)
+ opts.fixSpec.FixDir(containerParentDir)
+ opts.fixSpec.FixDir(bCacheParentDir)
+ opts.fixSpec.FixDir(bCacheDir)
+ trace.Trace("write props file:", propsFile)
+ err := os.WriteFile(propsFile, selectedEnv(), 0600)
+ if err != nil {
+ util.JustExitWith(err)
}
- return &a
+ opts.AddOption("-Djdisc.export.packages=")
+ opts.AddOption("-Djdisc.config.file=" + propsFile)
+ opts.AddOption("-Djdisc.cache.path=" + bCacheDir)
+ opts.AddOption("-Djdisc.logger.tag=" + svcName)
}
diff --git a/client/go/prog/spec_env.go b/client/go/prog/spec_env.go
index 498931fe92c..ffdafe7676b 100644
--- a/client/go/prog/spec_env.go
+++ b/client/go/prog/spec_env.go
@@ -22,31 +22,30 @@ func (p *Spec) Getenv(k string) string {
}
func (spec *Spec) effectiveEnv() []string {
- env := make(map[string]string)
- for _, entry := range os.Environ() {
- addInMap := func(kv string) bool {
- for idx, elem := range kv {
- if elem == '=' {
- k := kv[:idx]
- env[k] = kv
- return true
- }
+ envMap := make(map[string]string)
+ addToMap := func(kv string) {
+ for idx, elem := range kv {
+ if elem == '=' {
+ k := kv[:idx]
+ envMap[k] = kv
+ return
}
- return false
- }
- if !addInMap(entry) {
- env[entry] = ""
}
+ trace.Trace("invalid entry in os.Environ():", kv)
+ envMap[kv] = kv
+ }
+ for _, entry := range os.Environ() {
+ addToMap(entry)
}
for k, v := range spec.Env {
trace.Trace("add to environment:", k, "=", v)
- env[k] = k + "=" + v
+ envMap[k] = k + "=" + v
}
- envv := make([]string, 0, len(env))
- for _, v := range env {
- envv = append(envv, v)
+ envVec := make([]string, 0, len(envMap))
+ for _, val := range envMap {
+ envVec = append(envVec, val)
}
- return envv
+ return envVec
}
func (spec *Spec) considerFallback(varName, varValue string) {
diff --git a/client/go/trace/trace.go b/client/go/trace/trace.go
index cedd1bcf597..9f642b79562 100644
--- a/client/go/trace/trace.go
+++ b/client/go/trace/trace.go
@@ -31,30 +31,27 @@ func Silent() {
currentOutputLevel = levelNone
}
-func outputStderr(l outputLevel, n string, v ...interface{}) {
+func outputTracing(l outputLevel, n string, v ...interface{}) {
if l > currentOutputLevel {
return
}
- w := make([]interface{}, len(v)+1)
- w[0] = n
- for idx, arg := range v {
- w[idx+1] = arg
- }
- fmt.Fprintln(os.Stderr, w...)
+ out := os.Stderr
+ fmt.Fprintf(out, "%s\t", n)
+ fmt.Fprintln(out, v...)
}
func Info(v ...interface{}) {
- outputStderr(levelInfo, "[info]", v...)
+ outputTracing(levelInfo, "info", v...)
}
func Trace(v ...interface{}) {
- outputStderr(levelTrace, "[trace]", v...)
+ outputTracing(levelTrace, "info", v...)
}
func Debug(v ...interface{}) {
- outputStderr(levelDebug, "[debug]", v...)
+ outputTracing(levelDebug, "debug", v...)
}
func Warning(v ...interface{}) {
- outputStderr(levelWarning, "[warning]", v...)
+ outputTracing(levelWarning, "warning", v...)
}