summaryrefslogtreecommitdiffstats
path: root/client/go
diff options
context:
space:
mode:
Diffstat (limited to 'client/go')
-rw-r--r--client/go/script-utils/main.go5
-rw-r--r--client/go/script-utils/startcbinary/tuning.go6
-rw-r--r--client/go/util/io.go8
-rw-r--r--client/go/util/io_test.go43
-rw-r--r--client/go/util/setrlimit.go (renamed from client/go/script-utils/startcbinary/setrlimit.go)10
-rw-r--r--client/go/util/setrlimit_windows.go (renamed from client/go/script-utils/startcbinary/setrlimit_windows.go)4
-rw-r--r--client/go/vespa/find_user.go76
-rw-r--r--client/go/vespa/find_user_test.go27
-rw-r--r--client/go/vespa/load_env.go35
9 files changed, 168 insertions, 46 deletions
diff --git a/client/go/script-utils/main.go b/client/go/script-utils/main.go
index 189140158ae..a27e94a76a7 100644
--- a/client/go/script-utils/main.go
+++ b/client/go/script-utils/main.go
@@ -6,6 +6,7 @@ package main
import (
"fmt"
"os"
+ "runtime"
"strings"
"github.com/vespa-engine/vespa/client/go/cmd/clusterstate"
@@ -68,7 +69,9 @@ func main() {
func handleSimplePanic() {
if r := recover(); r != nil {
- if je, ok := r.(error); ok {
+ if rte, ok := r.(runtime.Error); ok {
+ panic(rte)
+ } else if je, ok := r.(error); ok {
fmt.Fprintln(os.Stderr, je)
os.Exit(1)
} else {
diff --git a/client/go/script-utils/startcbinary/tuning.go b/client/go/script-utils/startcbinary/tuning.go
index 80fec7cc6c2..dbe4d34dabe 100644
--- a/client/go/script-utils/startcbinary/tuning.go
+++ b/client/go/script-utils/startcbinary/tuning.go
@@ -44,7 +44,7 @@ func getThpSizeMb() int {
func (spec *ProgSpec) configureTuning() {
spec.optionallyReduceBaseFrequency()
- setResourceLimit(RLIMIT_CORE, NO_RLIMIT)
- setResourceLimit(RLIMIT_NOFILE, 262144)
- setResourceLimit(RLIMIT_NPROC, 409600)
+ util.SetResourceLimit(util.RLIMIT_CORE, util.NO_RLIMIT)
+ util.SetResourceLimit(util.RLIMIT_NOFILE, 262144)
+ util.SetResourceLimit(util.RLIMIT_NPROC, 409600)
}
diff --git a/client/go/util/io.go b/client/go/util/io.go
index 89f14c1a643..6aab64b8827 100644
--- a/client/go/util/io.go
+++ b/client/go/util/io.go
@@ -16,20 +16,20 @@ import (
// Returns true if the given path exists
func PathExists(path string) bool {
- _, err := os.Stat(path)
- return !errors.Is(err, os.ErrNotExist)
+ info, err := os.Stat(path)
+ return !errors.Is(err, os.ErrNotExist) && info != nil
}
// Returns true if the given path points to an existing directory
func IsDirectory(path string) bool {
info, err := os.Stat(path)
- return !errors.Is(err, os.ErrNotExist) && info.IsDir()
+ return !errors.Is(err, os.ErrNotExist) && info != nil && info.IsDir()
}
// Returns true if the given path points to an existing file
func IsRegularFile(path string) bool {
info, err := os.Stat(path)
- return !errors.Is(err, os.ErrNotExist) && info.Mode().IsRegular()
+ return !errors.Is(err, os.ErrNotExist) && info != nil && info.Mode().IsRegular()
}
// Returns the content of a reader as a string
diff --git a/client/go/util/io_test.go b/client/go/util/io_test.go
new file mode 100644
index 00000000000..ddfa2e624dd
--- /dev/null
+++ b/client/go/util/io_test.go
@@ -0,0 +1,43 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package util
+
+import (
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPathExists(t *testing.T) {
+ assert.Equal(t, true, PathExists("io.go"))
+ assert.Equal(t, false, PathExists("nosuchthing.go"))
+
+ tmpDir := t.TempDir()
+ err := os.MkdirAll(tmpDir+"/no", 0755)
+ assert.Nil(t, err)
+ err = os.MkdirAll(tmpDir+"/no/such", 0)
+ assert.Nil(t, err)
+ assert.Equal(t, false, PathExists(tmpDir+"/no/such/thing.go"))
+}
+
+func TestIsDir(t *testing.T) {
+ tmpDir := t.TempDir()
+ err := os.MkdirAll(tmpDir+"/no", 0755)
+ assert.Nil(t, err)
+ assert.Equal(t, true, IsDirectory(tmpDir+"/no"))
+ err = os.MkdirAll(tmpDir+"/no/such", 0)
+ assert.Nil(t, err)
+ assert.Equal(t, true, IsDirectory(tmpDir+"/no/such"))
+ assert.Equal(t, false, IsDirectory(tmpDir+"/no/such/thing.go"))
+}
+
+func TestIsRegularFile(t *testing.T) {
+ assert.Equal(t, true, IsRegularFile("io.go"))
+ assert.Equal(t, false, IsRegularFile("."))
+ tmpDir := t.TempDir()
+ err := os.MkdirAll(tmpDir+"/no", 0755)
+ assert.Nil(t, err)
+ err = os.MkdirAll(tmpDir+"/no/such", 0)
+ assert.Nil(t, err)
+ assert.Equal(t, false, IsRegularFile(tmpDir+"/no/such/thing.go"))
+}
diff --git a/client/go/script-utils/startcbinary/setrlimit.go b/client/go/util/setrlimit.go
index 5d7f33d5a0e..4ec1ea60a3c 100644
--- a/client/go/script-utils/startcbinary/setrlimit.go
+++ b/client/go/util/setrlimit.go
@@ -2,7 +2,7 @@
//go:build !windows
-package startcbinary
+package util
import (
"github.com/vespa-engine/vespa/client/go/trace"
@@ -31,7 +31,7 @@ func (rid ResourceId) String() string {
return "unknown resource id"
}
-func setResourceLimit(resource ResourceId, newVal uint64) {
+func SetResourceLimit(resource ResourceId, newVal uint64) {
var current unix.Rlimit
err := unix.Getrlimit(int(resource), &current)
if err != nil {
@@ -42,7 +42,11 @@ func setResourceLimit(resource ResourceId, newVal uint64) {
if current.Max < newVal {
if os.Getuid() == 0 {
wanted.Max = newVal
- } else {
+ } else if newVal > current.Max {
+ trace.Warning(
+ "Wanted", newVal,
+ "as limit for", resource.String(),
+ "but cannot exceed current hard limit:", current.Max)
newVal = current.Max
}
}
diff --git a/client/go/script-utils/startcbinary/setrlimit_windows.go b/client/go/util/setrlimit_windows.go
index 5bed1916246..c40b1cb1364 100644
--- a/client/go/script-utils/startcbinary/setrlimit_windows.go
+++ b/client/go/util/setrlimit_windows.go
@@ -2,7 +2,7 @@
//go:build windows
-package startcbinary
+package util
type ResourceId int
@@ -13,6 +13,6 @@ const (
NO_RLIMIT uint64 = ^uint64(0)
)
-func setResourceLimit(resource ResourceId, max uint64) {
+func SetResourceLimit(resource ResourceId, max uint64) {
// nop
}
diff --git a/client/go/vespa/find_user.go b/client/go/vespa/find_user.go
new file mode 100644
index 00000000000..c3f4e32906f
--- /dev/null
+++ b/client/go/vespa/find_user.go
@@ -0,0 +1,76 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// load default environment variables (from $VESPA_HOME/conf/vespa/default-env.txt)
+// Author: arnej
+
+package vespa
+
+import (
+ "os"
+ "os/user"
+ "strconv"
+)
+
+// Which user should vespa services run as? If current user is root,
+// we want to change to some non-privileged user.
+// Should be run after LoadDefaultEnv() which possibly loads VESPA_USER
+// Which user should vespa services run as? If current user is root,
+// we want to change to some non-privileged user.
+// Should be run after LoadDefaultEnv() which possibly loads VESPA_USER
+func FindVespaUser() string {
+ uName := os.Getenv("VESPA_USER")
+ if uName != "" {
+ // no check here, assume valid
+ return uName
+ }
+ if os.Getuid() == 0 {
+ u, err := user.Lookup("vespa")
+ if err == nil {
+ uName = u.Username
+ } else {
+ u, err = user.Lookup("nobody")
+ if err == nil {
+ uName = u.Username
+ }
+ }
+ }
+ if uName == "" {
+ u, err := user.Current()
+ if err == nil {
+ uName = u.Username
+ }
+ }
+ if uName != "" {
+ os.Setenv("VESPA_USER", uName)
+ }
+ return uName
+}
+
+// Which user/group should vespa services run as? If current user is root,
+// we want to change to some non-privileged user.
+// Should be run after LoadDefaultEnv() which possibly loads VESPA_USER
+
+func FindVespaUidAndGid() (userId, groupId int) {
+ userId = -1
+ groupId = -1
+ uName := os.Getenv("VESPA_USER")
+ gName := os.Getenv("VESPA_GROUP")
+ if uName == "" {
+ uName = FindVespaUser()
+ }
+ if uName != "" {
+ u, err := user.Lookup(uName)
+ if err == nil {
+ userId, _ = strconv.Atoi(u.Uid)
+ if gName == "" {
+ groupId, _ = strconv.Atoi(u.Gid)
+ }
+ }
+ }
+ if gName != "" {
+ g, err := user.LookupGroup(gName)
+ if err == nil {
+ groupId, _ = strconv.Atoi(g.Gid)
+ }
+ }
+ return
+}
diff --git a/client/go/vespa/find_user_test.go b/client/go/vespa/find_user_test.go
new file mode 100644
index 00000000000..3d533b08c56
--- /dev/null
+++ b/client/go/vespa/find_user_test.go
@@ -0,0 +1,27 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package vespa
+
+import (
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestFindVespaUser(t *testing.T) {
+ var uName string
+
+ t.Setenv("VESPA_USER", "nobody")
+ uName = FindVespaUser()
+ assert.Equal(t, "nobody", uName)
+
+ t.Setenv("VESPA_USER", "")
+ uName = FindVespaUser()
+ assert.NotEqual(t, "", uName)
+}
+
+func TestFindVespaUidAndGid(t *testing.T) {
+ uid, gid := FindVespaUidAndGid()
+ fmt.Fprintln(os.Stderr, "INFO: result from FindVespaUidAndGid() is", uid, "and", gid)
+}
diff --git a/client/go/vespa/load_env.go b/client/go/vespa/load_env.go
index 8eb7c841235..ec60305e1cc 100644
--- a/client/go/vespa/load_env.go
+++ b/client/go/vespa/load_env.go
@@ -8,7 +8,6 @@ import (
"bufio"
"fmt"
"os"
- "os/user"
"strings"
)
@@ -21,42 +20,12 @@ func LoadDefaultEnv() error {
func ExportDefaultEnvToSh() error {
holder := newShellEnvExporter()
err := loadDefaultEnvTo(holder)
+ holder.overrideVar("VESPA_HOME", FindHome())
+ holder.overrideVar("VESPA_USER", FindVespaUser())
holder.dump()
return err
}
-// Which user should vespa services run as? If current user is root,
-// we want to change to some non-privileged user.
-// Should be run after LoadDefaultEnv() which possibly loads VESPA_USER
-func FindVespaUser() string {
- uName := os.Getenv("VESPA_USER")
- if uName != "" {
- // no check here, assume valid
- return uName
- }
- if os.Getuid() == 0 {
- u, err := user.Lookup("vespa")
- if err == nil {
- uName = u.Username
- } else {
- u, err = user.Lookup("nobody")
- if err == nil {
- uName = u.Username
- }
- }
- }
- if uName == "" {
- u, err := user.Current()
- if err == nil {
- uName = u.Username
- }
- }
- if uName != "" {
- os.Setenv("VESPA_USER", uName)
- }
- return uName
-}
-
type loadEnvReceiver interface {
fallbackVar(varName, varVal string)
overrideVar(varName, varVal string)