diff options
Diffstat (limited to 'client/go')
-rw-r--r-- | client/go/script-utils/main.go | 5 | ||||
-rw-r--r-- | client/go/script-utils/startcbinary/tuning.go | 6 | ||||
-rw-r--r-- | client/go/util/io.go | 8 | ||||
-rw-r--r-- | client/go/util/io_test.go | 43 | ||||
-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.go | 76 | ||||
-rw-r--r-- | client/go/vespa/find_user_test.go | 27 | ||||
-rw-r--r-- | client/go/vespa/load_env.go | 35 |
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), ¤t) 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) |