diff options
87 files changed, 432 insertions, 261 deletions
diff --git a/client/go/.gitignore b/client/go/.gitignore index d3ce9b1989b..b35a2cef362 100644 --- a/client/go/.gitignore +++ b/client/go/.gitignore @@ -1,3 +1,5 @@ bin/ +share/ !Makefile +!build/ !target/ diff --git a/client/go/Makefile b/client/go/Makefile index 40f0a4aaf0e..3297b628cb2 100644 --- a/client/go/Makefile +++ b/client/go/Makefile @@ -1,15 +1,24 @@ # Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -all: test checkfmt install - +BIN ?= $(CURDIR)/bin +SHARE ?= $(CURDIR)/share # When building a new release the build system should set the VERSION # environment variable to version being built VERSION ?= $(shell echo "0.0.0-`git rev-parse --short HEAD`") +all: test checkfmt install + install: - env GOBIN=$(CURDIR)/bin \ + env GOBIN=$(BIN) \ go install -ldflags "-X github.com/vespa-engine/vespa/client/go/build.Version=$(VERSION)" ./... +manpages: install + mkdir -p $(SHARE)/man/man1 + $(BIN)/vespa man $(SHARE)/man/man1 + +clean: + rm -rf $(BIN) $(SHARE) + test: go test ./... diff --git a/client/go/build/build.go b/client/go/build/build.go new file mode 100644 index 00000000000..a51518dbb8f --- /dev/null +++ b/client/go/build/build.go @@ -0,0 +1,3 @@ +package build + +var Version string = "0.0.0-devel" // Overriden by linker flag as part of build diff --git a/client/go/cmd/api_key.go b/client/go/cmd/api_key.go index c3a111b0f15..b465a3b8add 100644 --- a/client/go/cmd/api_key.go +++ b/client/go/cmd/api_key.go @@ -23,10 +23,11 @@ func init() { } var apiKeyCmd = &cobra.Command{ - Use: "api-key", - Short: "Create a new user API key for authentication with Vespa Cloud", - Example: "$ vespa api-key -a my-tenant.my-app.my-instance", - Args: cobra.ExactArgs(0), + Use: "api-key", + Short: "Create a new user API key for authentication with Vespa Cloud", + Example: "$ vespa api-key -a my-tenant.my-app.my-instance", + DisableAutoGenTag: true, + Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { configDir := configDir("") if configDir == "" { diff --git a/client/go/cmd/cert.go b/client/go/cmd/cert.go index 0cf220783d5..e1e11b6f73e 100644 --- a/client/go/cmd/cert.go +++ b/client/go/cmd/cert.go @@ -22,10 +22,11 @@ func init() { } var certCmd = &cobra.Command{ - Use: "cert", - Short: "Create a new private key and self-signed certificate for Vespa Cloud deployment", - Example: "$ vespa cert -a my-tenant.my-app.my-instance", - Args: cobra.MaximumNArgs(1), + Use: "cert", + Short: "Create a new private key and self-signed certificate for Vespa Cloud deployment", + Example: "$ vespa cert -a my-tenant.my-app.my-instance", + DisableAutoGenTag: true, + Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { app := getApplication() pkg, err := vespa.ApplicationPackageFrom(applicationSource(args)) diff --git a/client/go/cmd/clone.go b/client/go/cmd/clone.go index 39281d408a5..ffd77030935 100644 --- a/client/go/cmd/clone.go +++ b/client/go/cmd/clone.go @@ -36,7 +36,8 @@ var cloneCmd = &cobra.Command{ Example: "$ vespa clone vespa-cloud/album-recommendation my-app", The application package is copied from a sample application in https://github.com/vespa-engine/sample-apps`, - Args: cobra.ExactArgs(2), + DisableAutoGenTag: true, + Args: cobra.ExactArgs(2), Run: func(cmd *cobra.Command, args []string) { cloneApplication(args[0], args[1]) }, diff --git a/client/go/cmd/config.go b/client/go/cmd/config.go index 56d4321c11d..bb1662d0b07 100644 --- a/client/go/cmd/config.go +++ b/client/go/cmd/config.go @@ -32,8 +32,9 @@ func init() { } var configCmd = &cobra.Command{ - Use: "config", - Short: "Configure default values for flags", + Use: "config", + Short: "Configure default values for flags", + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { // Root command does nothing cmd.Help() @@ -42,10 +43,11 @@ var configCmd = &cobra.Command{ } var setConfigCmd = &cobra.Command{ - Use: "set <option> <value>", - Short: "Set a configuration option.", - Example: "$ vespa config set target cloud", - Args: cobra.ExactArgs(2), + Use: "set <option> <value>", + Short: "Set a configuration option.", + Example: "$ vespa config set target cloud", + DisableAutoGenTag: true, + Args: cobra.ExactArgs(2), Run: func(cmd *cobra.Command, args []string) { if err := setOption(args[0], args[1]); err != nil { log.Print(err) @@ -56,10 +58,11 @@ var setConfigCmd = &cobra.Command{ } var getConfigCmd = &cobra.Command{ - Use: "get [<option>]", - Short: "Get a configuration option", - Example: "$ vespa config get target", - Args: cobra.MaximumNArgs(1), + Use: "get [<option>]", + Short: "Get a configuration option", + Example: "$ vespa config get target", + Args: cobra.MaximumNArgs(1), + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { // Print all values printOption(targetFlag) diff --git a/client/go/cmd/deploy.go b/client/go/cmd/deploy.go index 2a9ababddaa..f44d3aeae42 100644 --- a/client/go/cmd/deploy.go +++ b/client/go/cmd/deploy.go @@ -33,15 +33,18 @@ func init() { } var deployCmd = &cobra.Command{ - Use: "deploy <application-directory>", + Use: "deploy [<application-directory>]", Short: "Deploy (prepare and activate) an application package", Long: `Deploy (prepare and activate) an application package. When this returns successfully the application package has been validated and activated on config servers. The process of applying it on individual nodes -has started but may not have completed.`, - Example: "$ vespa deploy .", - Args: cobra.MaximumNArgs(1), +has started but may not have completed. + +If application directory is not specified, it defaults to working directory.`, + Example: "$ vespa deploy .", + Args: cobra.MaximumNArgs(1), + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { pkg, err := vespa.ApplicationPackageFrom(applicationSource(args)) if err != nil { @@ -72,9 +75,10 @@ has started but may not have completed.`, } var prepareCmd = &cobra.Command{ - Use: "prepare <application-directory>", - Short: "Prepare an application package for activation", - Args: cobra.MaximumNArgs(1), + Use: "prepare <application-directory>", + Short: "Prepare an application package for activation", + Args: cobra.MaximumNArgs(1), + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { pkg, err := vespa.ApplicationPackageFrom(applicationSource(args)) if err != nil { @@ -100,9 +104,10 @@ var prepareCmd = &cobra.Command{ } var activateCmd = &cobra.Command{ - Use: "activate", - Short: "Activate (deploy) a previously prepared application package", - Args: cobra.MaximumNArgs(1), + Use: "activate", + Short: "Activate (deploy) a previously prepared application package", + Args: cobra.MaximumNArgs(1), + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { pkg, err := vespa.ApplicationPackageFrom(applicationSource(args)) if err != nil { diff --git a/client/go/cmd/document.go b/client/go/cmd/document.go index daea27a0815..8a438ad4125 100644 --- a/client/go/cmd/document.go +++ b/client/go/cmd/document.go @@ -34,8 +34,9 @@ subsequent get or query operation. To feed with high throughput, https://docs.vespa.ai/en/vespa-feed-client.html should be used instead of this.`, - Example: `$ vespa document src/test/resources/A-Head-Full-of-Dreams.json`, - Args: cobra.ExactArgs(1), + Example: `$ vespa document src/test/resources/A-Head-Full-of-Dreams.json`, + DisableAutoGenTag: true, + Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { printResult(vespa.Send(args[0], documentService()), false) }, @@ -50,6 +51,7 @@ If the document id is specified both as an argument and in the file the argument Args: cobra.RangeArgs(1, 2), Example: `$ vespa document put src/test/resources/A-Head-Full-of-Dreams.json $ vespa document put id:mynamespace:music::a-head-full-of-dreams src/test/resources/A-Head-Full-of-Dreams.json`, + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { if len(args) == 1 { printResult(vespa.Put("", args[0], documentService()), false) @@ -67,6 +69,7 @@ If the document id is specified both as an argument and in the file the argument Args: cobra.RangeArgs(1, 2), Example: `$ vespa document update src/test/resources/A-Head-Full-of-Dreams-Update.json $ vespa document update id:mynamespace:music::a-head-full-of-dreams src/test/resources/A-Head-Full-of-Dreams.json`, + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { if len(args) == 1 { printResult(vespa.Update("", args[0], documentService()), false) @@ -84,6 +87,7 @@ If the document id is specified both as an argument and in the file the argument Args: cobra.ExactArgs(1), Example: `$ vespa document remove src/test/resources/A-Head-Full-of-Dreams-Remove.json $ vespa document remove id:mynamespace:music::a-head-full-of-dreams`, + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { if strings.HasPrefix(args[0], "id:") { printResult(vespa.RemoveId(args[0], documentService()), false) @@ -94,9 +98,10 @@ $ vespa document remove id:mynamespace:music::a-head-full-of-dreams`, } var documentGetCmd = &cobra.Command{ - Use: "get <id>", - Short: "Gets a document", - Args: cobra.ExactArgs(1), + Use: "get <id>", + Short: "Gets a document", + Args: cobra.ExactArgs(1), + DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { printResult(vespa.Get(args[0], documentService()), true) }, diff --git a/client/go/cmd/man.go b/client/go/cmd/man.go new file mode 100644 index 00000000000..0bd80f3d985 --- /dev/null +++ b/client/go/cmd/man.go @@ -0,0 +1,27 @@ +package cmd + +import ( + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" +) + +func init() { + rootCmd.AddCommand(manCmd) +} + +var manCmd = &cobra.Command{ + Use: "man <directory>", + Short: "Generate man pages and write them to given directory", + Args: cobra.ExactArgs(1), + Hidden: true, // Not intended to be called by users + DisableAutoGenTag: true, + Run: func(cmd *cobra.Command, args []string) { + dir := args[0] + err := doc.GenManTree(rootCmd, nil, dir) + if err != nil { + fatalErr(err, "Failed to write man pages") + return + } + printSuccess("Man pages written to ", dir) + }, +} diff --git a/client/go/cmd/man_test.go b/client/go/cmd/man_test.go new file mode 100644 index 00000000000..59efc64b8de --- /dev/null +++ b/client/go/cmd/man_test.go @@ -0,0 +1,17 @@ +package cmd + +import ( + "fmt" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/vespa-engine/vespa/client/go/util" +) + +func TestMan(t *testing.T) { + tmpDir := t.TempDir() + out := execute(command{args: []string{"man", tmpDir}}, t, nil) + assert.Equal(t, fmt.Sprintf("Success: Man pages written to %s\n", tmpDir), out) + assert.True(t, util.PathExists(filepath.Join(tmpDir, "vespa.1"))) +} diff --git a/client/go/cmd/query.go b/client/go/cmd/query.go index 778873b6818..062ea8d1bbc 100644 --- a/client/go/cmd/query.go +++ b/client/go/cmd/query.go @@ -28,7 +28,8 @@ var queryCmd = &cobra.Command{ Any parameter from https://docs.vespa.ai/en/reference/query-api-reference.html can be set by the syntax [parameter-name]=[value].`, // TODO: Support referencing a query json file - Args: cobra.MinimumNArgs(1), + DisableAutoGenTag: true, + Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { query(args) }, diff --git a/client/go/cmd/root.go b/client/go/cmd/root.go index 73db7ebbfc6..fde7d6edb5a 100644 --- a/client/go/cmd/root.go +++ b/client/go/cmd/root.go @@ -26,7 +26,9 @@ Use it on Vespa instances running locally, remotely or in the cloud. Prefer web service API's to this in production. Vespa documentation: https://docs.vespa.ai`, + DisableAutoGenTag: true, } + color aurora.Aurora targetArg string applicationArg string @@ -53,6 +55,7 @@ func init() { rootCmd.PersistentFlags().IntVarP(&waitSecsArg, waitFlag, "w", 0, "Number of seconds to wait for a service to become ready") bindFlagToConfig(targetFlag, rootCmd) bindFlagToConfig(applicationFlag, rootCmd) + bindFlagToConfig(waitFlag, rootCmd) } // Execute executes the root command. diff --git a/client/go/cmd/status.go b/client/go/cmd/status.go index 8764cddbb91..796ede9c86d 100644 --- a/client/go/cmd/status.go +++ b/client/go/cmd/status.go @@ -16,40 +16,44 @@ func init() { } var statusCmd = &cobra.Command{ - Use: "status", - Short: "Verify that a service is ready to use (query by default)", - Example: `$ vespa status query`, - Args: cobra.MaximumNArgs(1), + Use: "status", + Short: "Verify that a service is ready to use (query by default)", + Example: `$ vespa status query`, + DisableAutoGenTag: true, + Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { waitForService("query") }, } var statusQueryCmd = &cobra.Command{ - Use: "query", - Short: "Verify that the query service is ready to use (default)", - Example: `$ vespa status query`, - Args: cobra.ExactArgs(0), + Use: "query", + Short: "Verify that the query service is ready to use (default)", + Example: `$ vespa status query`, + DisableAutoGenTag: true, + Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { waitForService("query") }, } var statusDocumentCmd = &cobra.Command{ - Use: "document", - Short: "Verify that the document service is ready to use", - Example: `$ vespa status document`, - Args: cobra.ExactArgs(0), + Use: "document", + Short: "Verify that the document service is ready to use", + Example: `$ vespa status document`, + DisableAutoGenTag: true, + Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { waitForService("document") }, } var statusDeployCmd = &cobra.Command{ - Use: "deploy", - Short: "Verify that the deploy service is ready to use", - Example: `$ vespa status deploy`, - Args: cobra.ExactArgs(0), + Use: "deploy", + Short: "Verify that the deploy service is ready to use", + Example: `$ vespa status deploy`, + DisableAutoGenTag: true, + Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { waitForService("deploy") }, diff --git a/client/go/cmd/version.go b/client/go/cmd/version.go index c9146fc1f92..4a5b6ec71b3 100644 --- a/client/go/cmd/version.go +++ b/client/go/cmd/version.go @@ -12,9 +12,10 @@ func init() { } var versionCmd = &cobra.Command{ - Use: "version", - Short: "Show version number", - Args: cobra.ExactArgs(0), + Use: "version", + Short: "Show version number", + DisableAutoGenTag: true, + Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { log.Print("vespa version ", build.Version) }, diff --git a/client/go/go.sum b/client/go/go.sum index cec273d1506..826f137d5e2 100644 --- a/client/go/go.sum +++ b/client/go/go.sum @@ -55,6 +55,7 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -209,9 +210,11 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/client/go/vespa/deploy.go b/client/go/vespa/deploy.go index dd66edf7122..c2a27442a53 100644 --- a/client/go/vespa/deploy.go +++ b/client/go/vespa/deploy.go @@ -146,7 +146,7 @@ func ZoneFromString(s string) (ZoneID, error) { // Prepare deployment and return the session ID func Prepare(deployment DeploymentOpts) (int64, error) { if deployment.IsCloud() { - return 0, fmt.Errorf("%s: prepare is not supported", deployment) + return 0, fmt.Errorf("prepare is not supported with %s target", deployment.Target.Type()) } sessionURL, err := deployment.url("/application/v2/tenant/default/session") if err != nil { @@ -179,7 +179,7 @@ func Prepare(deployment DeploymentOpts) (int64, error) { // Activate deployment with sessionID from a past prepare func Activate(sessionID int64, deployment DeploymentOpts) error { if deployment.IsCloud() { - return fmt.Errorf("%s: activate is not supported", deployment) + return fmt.Errorf("activate is not supported with %s target", deployment.Target.Type()) } u, err := deployment.url(fmt.Sprintf("/application/v2/tenant/default/session/%d/active", sessionID)) if err != nil { diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java index 326728aab3f..92a394d7036 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java @@ -80,8 +80,8 @@ public interface ModelContext { @ModelFeatureFlag(owners = {"baldersheim"}) default boolean useAsyncMessageHandlingOnSchedule() { throw new UnsupportedOperationException("TODO specify default value"); } @ModelFeatureFlag(owners = {"baldersheim"}) default double feedConcurrency() { throw new UnsupportedOperationException("TODO specify default value"); } @ModelFeatureFlag(owners = {"baldersheim"}) default int metricsproxyNumThreads() { throw new UnsupportedOperationException("TODO specify default value"); } - @ModelFeatureFlag(owners = {"baldersheim"}) default int largeRankExpressionLimit() { return 0x10000; } - @ModelFeatureFlag(owners = {"baldersheim"}) default boolean useExternalRankExpressions() { return false; } + @ModelFeatureFlag(owners = {"baldersheim"}) default int largeRankExpressionLimit() { return 8192; } + @ModelFeatureFlag(owners = {"baldersheim"}) default boolean useExternalRankExpressions() { return true; } @ModelFeatureFlag(owners = {"baldersheim"}) default boolean distributeExternalRankExpressions() { return false; } @ModelFeatureFlag(owners = {"baldersheim"}) default int maxConcurrentMergesPerNode() { throw new UnsupportedOperationException("TODO specify default value"); } @ModelFeatureFlag(owners = {"baldersheim"}) default int maxMergeQueueSize() { throw new UnsupportedOperationException("TODO specify default value"); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java index ec5da9baa11..a876ba7c3a0 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java @@ -782,6 +782,8 @@ public class VespaMetricSet { metrics.add(new Metric("vds.mergethrottler.bounced_due_to_back_pressure.rate")); metrics.add(new Metric("vds.mergethrottler.locallyexecutedmerges.ok.rate")); metrics.add(new Metric("vds.mergethrottler.mergechains.ok.rate")); + metrics.add(new Metric("vds.mergethrottler.mergechains.failures.busy.rate")); + metrics.add(new Metric("vds.mergethrottler.mergechains.failures.total.rate")); return metrics; } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java b/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java index f0a2e52f6bf..b5fe4ddee41 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/Distributor.java @@ -49,14 +49,18 @@ public class Distributor extends ContentNode implements StorDistributormanagerCo } private int tuneNumDistributorStripes() { - if ((numDistributorStripesFlag == -1) && (getHostResource() != null)) { - int cores = (int)getHostResource().realResources().vcpu(); - if (cores <= 16) { - return 1; - } else if (cores <= 64) { - return 2; + if (numDistributorStripesFlag == -1) { + if (getHostResource() != null) { + int cores = (int)getHostResource().realResources().vcpu(); + if (cores <= 16) { + return 1; + } else if (cores <= 64) { + return 2; + } else { + return 4; + } } else { - return 4; + return 1; } } return numDistributorStripesFlag; diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java index c79238ed1d6..c7c02c581f9 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java @@ -1079,6 +1079,7 @@ public class ContentClusterTest extends ContentBaseTest { assertEquals(0, resolveNumDistributorStripesConfigWithFeatureFlag(new TestProperties(), Optional.empty())); assertEquals(0, resolveNumDistributorStripesConfigWithFeatureFlag(0)); assertEquals(1, resolveNumDistributorStripesConfigWithFeatureFlag(1)); + assertEquals(1, resolveNumDistributorStripesConfigWithFeatureFlag(-1)); assertEquals(4, resolveNumDistributorStripesConfigWithFeatureFlag(4)); } diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java index d3a1bfb50a9..be71f230934 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription.impl; import com.yahoo.config.ConfigInstance; @@ -11,6 +11,7 @@ import java.lang.reflect.Constructor; /** * Subscription on a programmatically built set of configs + * * @author Vegard Havdal */ public class ConfigSetSubscription<T extends ConfigInstance> extends ConfigSubscription<T> { @@ -20,11 +21,11 @@ public class ConfigSetSubscription<T extends ConfigInstance> extends ConfigSubsc ConfigSetSubscription(ConfigKey<T> key, ConfigSubscriber subscriber, ConfigSource cset) { super(key, subscriber); - if (!(cset instanceof ConfigSet)) throw new IllegalArgumentException("Source is not a ConfigSet: "+cset); - this.set=(ConfigSet) cset; + if (!(cset instanceof ConfigSet)) throw new IllegalArgumentException("Source is not a ConfigSet: " + cset); + this.set = (ConfigSet) cset; subKey = new ConfigKey<>(configClass, key.getConfigId()); if (!set.contains(subKey)) { - throw new IllegalArgumentException("The given ConfigSet "+set+" does not contain a config for "+subKey); + throw new IllegalArgumentException("The given ConfigSet " + set + " does not contain a config for " + subKey); } setGeneration(0L); } diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java index 9c535d7114f..53a9f3f9f94 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java @@ -1,10 +1,6 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription.impl; -import java.io.File; -import java.util.concurrent.atomic.AtomicReference; -import java.util.logging.Logger; - import com.yahoo.config.ConfigInstance; import com.yahoo.config.subscription.ConfigSet; import com.yahoo.config.subscription.ConfigSource; @@ -18,6 +14,10 @@ import com.yahoo.vespa.config.ConfigKey; import com.yahoo.vespa.config.TimingValues; import com.yahoo.vespa.config.protocol.DefContent; +import java.io.File; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Logger; + /** * Represents one active subscription to one config * @@ -40,36 +40,44 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { private final T config; private final Long generation; private final boolean applyOnRestart; + private final PayloadChecksum payloadChecksum; private ConfigState(boolean generationChanged, Long generation, boolean applyOnRestart, boolean configChanged, - T config) { + T config, + PayloadChecksum payloadChecksum) { this.generationChanged = generationChanged; this.generation = generation; this.applyOnRestart = applyOnRestart; this.configChanged = configChanged; this.config = config; + this.payloadChecksum = payloadChecksum; } - private ConfigState(Long generation, T config) { - this(false, generation, false, false, config); + private ConfigState(Long generation, T config, PayloadChecksum payloadChecksum) { + this(false, generation, false, false, config, payloadChecksum); } private ConfigState() { - this(false, 0L, false, false, null); + this(false, 0L, false, false, null, PayloadChecksum.empty()); } - private ConfigState<T> createUnchanged() { return new ConfigState<>(generation, config); } + private ConfigState<T> createUnchanged() { return new ConfigState<>(generation, config, payloadChecksum); } + public boolean isConfigChanged() { return configChanged; } + public boolean isGenerationChanged() { return generationChanged; } + public Long getGeneration() { return generation; } public boolean applyOnRestart() { return applyOnRestart; } public T getConfig() { return config; } + public PayloadChecksum getChecksum() { return payloadChecksum; } + } /** @@ -86,7 +94,7 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { /** * Initializes one subscription * - * @param key a {@link ConfigKey} + * @param key a {@link ConfigKey} * @param subscriber the subscriber for this subscription */ ConfigSubscription(ConfigKey<T> key, ConfigSubscriber subscriber) { @@ -96,11 +104,10 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { this.config.set(new ConfigState<>()); } - /** * Correct type of ConfigSubscription instance based on type of source or form of config id * - * @param key a {@link ConfigKey} + * @param key a {@link ConfigKey} * @param subscriber the subscriber for this subscription * @return a subclass of a ConfigsSubscription */ @@ -113,19 +120,19 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { if (source instanceof JarSource || configId.startsWith("jar:")) return getJarSub(key, subscriber, source); if (source instanceof ConfigSet) return new ConfigSetSubscription<>(key, subscriber, source); if (source instanceof ConfigSourceSet) return new JRTConfigSubscription<>(key, subscriber, source, timingValues); - throw new IllegalArgumentException("Unknown source type: "+source); + throw new IllegalArgumentException("Unknown source type: " + source); } private static <T extends ConfigInstance> JarConfigSubscription<T> getJarSub( ConfigKey<T> key, ConfigSubscriber subscriber, ConfigSource source) { String jarName; - String path="config/"; + String path = "config/"; if (source instanceof JarSource) { JarSource js = (JarSource) source; - jarName=js.getJarFile().getName(); - if (js.getPath()!=null) path=js.getPath(); + jarName = js.getJarFile().getName(); + if (js.getPath() != null) path = js.getPath(); } else { - jarName=key.getConfigId().replace("jar:", "").replaceFirst("\\!/.*", ""); + jarName = key.getConfigId().replace("jar:", "").replaceFirst("\\!/.*", ""); if (key.getConfigId().contains("!/")) path = key.getConfigId().replaceFirst(".*\\!/", ""); } return new JarConfigSubscription<>(key, subscriber, jarName, path); @@ -133,20 +140,27 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { private static <T extends ConfigInstance> ConfigSubscription<T> getFileSub( ConfigKey<T> key, ConfigSubscriber subscriber, ConfigSource source) { - File file = ((source instanceof FileSource))?((FileSource)source).getFile():new File(key.getConfigId().replace("file:", "")); + File file = ((source instanceof FileSource)) + ? ((FileSource) source).getFile() + : new File(key.getConfigId().replace("file:", "")); return new FileConfigSubscription<>(key, subscriber, file); } - private static <T extends ConfigInstance> ConfigSubscription<T> getRawSub( - ConfigKey<T> key, ConfigSubscriber subscriber, ConfigSource source) { - String payload = ((source instanceof RawSource)?((RawSource)source).payload:key.getConfigId().replace("raw:", "")); - return new RawConfigSubscription<>(key, subscriber,payload); + private static <T extends ConfigInstance> ConfigSubscription<T> getRawSub(ConfigKey<T> key, + ConfigSubscriber subscriber, + ConfigSource source) { + String payload = ((source instanceof RawSource) + ? ((RawSource) source).payload + : key.getConfigId().replace("raw:", "")); + return new RawConfigSubscription<>(key, subscriber, payload); } - private static <T extends ConfigInstance> ConfigSubscription<T> getDirFileSub(ConfigKey<T> key, ConfigSubscriber subscriber, ConfigSource source) { + private static <T extends ConfigInstance> ConfigSubscription<T> getDirFileSub(ConfigKey<T> key, + ConfigSubscriber subscriber, + ConfigSource source) { String dir = key.getConfigId().replace("dir:", ""); if (source instanceof DirSource) { - dir = ((DirSource)source).getDir().toString(); + dir = ((DirSource) source).getDir().toString(); } if (!dir.endsWith(File.separator)) dir = dir + File.separator; String name = getConfigFilename(key); @@ -174,36 +188,38 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { */ public boolean isConfigChangedAndReset(Long requiredGen) { ConfigState<T> prev = config.get(); - while ( prev.getGeneration().equals(requiredGen) && !config.compareAndSet(prev, prev.createUnchanged())) { + while (prev.getGeneration().equals(requiredGen) && !config.compareAndSet(prev, prev.createUnchanged())) { prev = config.get(); } // A false positive is a lot better than a false negative return !prev.getGeneration().equals(requiredGen) || prev.isConfigChanged(); } - void setConfig(Long generation, boolean applyOnRestart, T config) { - this.config.set(new ConfigState<>(true, generation, applyOnRestart, true, config)); + void setConfig(Long generation, boolean applyOnRestart, T config, PayloadChecksum payloadChecksum) { + this.config.set(new ConfigState<>(true, generation, applyOnRestart, true, config, payloadChecksum)); } - /** Used by {@link FileConfigSubscription} and {@link ConfigSetSubscription} */ + /** + * Used by {@link FileConfigSubscription} and {@link ConfigSetSubscription} + */ protected void setConfigIncGen(T config) { ConfigState<T> prev = this.config.get(); - this.config.set(new ConfigState<>(true, prev.getGeneration() + 1, prev.applyOnRestart(), true, config)); + this.config.set(new ConfigState<>(true, prev.getGeneration() + 1, prev.applyOnRestart(), true, config, prev.payloadChecksum)); } protected void setConfigIfChanged(T config) { ConfigState<T> prev = this.config.get(); - this.config.set(new ConfigState<>(true, prev.getGeneration(), prev.applyOnRestart(), !config.equals(prev.getConfig()), config)); + this.config.set(new ConfigState<>(true, prev.getGeneration(), prev.applyOnRestart(), !config.equals(prev.getConfig()), config, prev.payloadChecksum)); } void setGeneration(Long generation) { ConfigState<T> prev = config.get(); - this.config.set(new ConfigState<>(true, generation, prev.applyOnRestart(), prev.isConfigChanged(), prev.getConfig())); + this.config.set(new ConfigState<>(true, generation, prev.applyOnRestart(), prev.isConfigChanged(), prev.getConfig(), prev.payloadChecksum)); } void setApplyOnRestart(boolean applyOnRestart) { ConfigState<T> prev = config.get(); - this.config.set(new ConfigState<>(prev.isGenerationChanged(), prev.getGeneration(), applyOnRestart, prev.isConfigChanged(), prev.getConfig())); + this.config.set(new ConfigState<>(prev.isGenerationChanged(), prev.getGeneration(), applyOnRestart, prev.isConfigChanged(), prev.getConfig(), prev.payloadChecksum)); } /** @@ -211,13 +227,13 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { * * @return the ConfigInstance (the config) of this subscription */ - public ConfigState<T> getConfigState() { return config.get(); } /** * The class of the subscription's desired {@link ConfigInstance} + * * @return the config class */ public Class<T> getConfigClass() { @@ -251,7 +267,7 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { * * @param timeout in milliseconds * @return false if timed out, true if generation or config or {@link #exception} changed. If true, the {@link #config} field will be set also. - * has changed + * has changed */ public abstract boolean nextConfig(long timeout); @@ -311,6 +327,7 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { /** * Force this into the given generation, used in testing + * * @param generation a config generation */ public void reload(long generation) { diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java index ce375f9fdbf..3282bc81e55 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription.impl; import com.yahoo.config.ConfigInstance; @@ -29,14 +29,14 @@ public class FileConfigSubscription<T extends ConfigInstance> extends ConfigSubs FileConfigSubscription(ConfigKey<T> key, ConfigSubscriber subscriber, File f) { super(key, subscriber); setGeneration(0L); - file=f; + file = f; if (!file.exists() && !file.isFile()) - throw new IllegalArgumentException("Not a file: "+file); + throw new IllegalArgumentException("Not a file: " + file); } @Override public boolean nextConfig(long timeout) { - if (!file.exists() && !file.isFile()) throw new IllegalArgumentException("Not a file: "+file); + if (!file.exists() && !file.isFile()) throw new IllegalArgumentException("Not a file: " + file); if (checkReloaded()) { log.log(FINE, () -> "User forced config reload at " + System.currentTimeMillis()); // User forced reload @@ -46,7 +46,7 @@ public class FileConfigSubscription<T extends ConfigInstance> extends ConfigSubs log.log(FINE, () -> "Config: " + configState.getConfig().toString()); return true; } - if (file.lastModified()!=ts) { + if (file.lastModified() != ts) { setConfigIncGen(updateConfig()); return true; } @@ -60,7 +60,7 @@ public class FileConfigSubscription<T extends ConfigInstance> extends ConfigSubs } private T updateConfig() { - ts=file.lastModified(); + ts = file.lastModified(); try { ConfigPayload payload = new CfgConfigPayloadBuilder().deserialize(Arrays.asList(IOUtils.readFile(file).split("\n"))); return payload.toInstance(configClass, key.getConfigId()); diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java index b052c79f429..05d4a33c02a 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java @@ -1,8 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription.impl; -import java.util.List; - import com.yahoo.config.subscription.ConfigSource; import com.yahoo.config.subscription.ConfigSubscriber; import com.yahoo.vespa.config.ConfigKey; @@ -11,6 +9,8 @@ import com.yahoo.vespa.config.TimingValues; import com.yahoo.vespa.config.protocol.DefContent; import com.yahoo.vespa.config.protocol.JRTClientConfigRequest; +import java.util.List; + import static java.util.logging.Level.FINE; /** @@ -32,7 +32,8 @@ public class GenericJRTConfigSubscription extends JRTConfigSubscription<RawConfi @Override protected void setNewConfig(JRTClientConfigRequest jrtReq) { - setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsApplyOnRestart(), RawConfig.createFromResponseParameters(jrtReq) ); + RawConfig rawConfig = RawConfig.createFromResponseParameters(jrtReq); + setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsApplyOnRestart(), rawConfig, new PayloadChecksum(jrtReq.getNewConfigMd5())); log.log(FINE, () -> "in setNewConfig, config=" + this.getConfigState().getConfig()); } diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java index d3562a47ea1..853bc4dfc00 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java @@ -68,7 +68,9 @@ public class JRTConfigRequester implements RequestWaiter { this.timingValues = timingValues; } - /** Only for testing */ + /** + * Only for testing + */ public JRTConfigRequester(ConnectionPool connectionPool, TimingValues timingValues) { this(null, new ScheduledThreadPoolExecutor(1), connectionPool, timingValues); } @@ -90,12 +92,12 @@ public class JRTConfigRequester implements RequestWaiter { private <T extends ConfigInstance> void doRequest(JRTConfigSubscription<T> sub, JRTClientConfigRequest req) { Connection connection = connectionPool.getCurrent(); req.getRequest().setContext(new RequestContext(sub, req, connection)); - if ( ! req.validateParameters()) throw new ConfigurationRuntimeException("Error in parameters for config request: " + req); + if (!req.validateParameters()) throw new ConfigurationRuntimeException("Error in parameters for config request: " + req); double jrtClientTimeout = getClientTimeout(req); log.log(FINE, () -> "Requesting config for " + sub + " on connection " + connection - + " with client timeout " + jrtClientTimeout + - (log.isLoggable(FINEST) ? (",defcontent=" + req.getDefContent().asString()) : "")); + + " with client timeout " + jrtClientTimeout + + (log.isLoggable(FINEST) ? (",defcontent=" + req.getDefContent().asString()) : "")); connection.invokeAsync(req.getRequest(), jrtClientTimeout, this); } @@ -177,7 +179,7 @@ public class JRTConfigRequester implements RequestWaiter { boolean fatalFailures, TimingValues timingValues, boolean configured) { - long delay = (configured ? timingValues.getConfiguredErrorDelay(): timingValues.getUnconfiguredDelay()); + long delay = configured ? timingValues.getConfiguredErrorDelay() : timingValues.getUnconfiguredDelay(); switch (errorType) { case TRANSIENT: @@ -199,7 +201,7 @@ public class JRTConfigRequester implements RequestWaiter { Connection connection) { fatalFailures = false; log.log(INFO, "Connection to " + connection.getAddress() + - " failed or timed out, clients will keep existing config, will keep trying."); + " failed or timed out, clients will keep existing config, will keep trying."); scheduleNextRequest(jrtReq, sub, delay, calculateErrorTimeout()); } diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java index b48e5905239..b06f986555c 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription.impl; import com.yahoo.config.ConfigInstance; @@ -111,7 +111,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc } catch (IllegalArgumentException e) { badConfigE = e; } - setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsApplyOnRestart(), configInstance); + setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsApplyOnRestart(), configInstance, new PayloadChecksum(jrtReq.getNewConfigMd5())); if (badConfigE != null) { throw new IllegalArgumentException("Bad config from jrt", badConfigE); } @@ -129,7 +129,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc Payload payload = jrtRequest.getNewPayload(); ConfigPayload configPayload = ConfigPayload.fromUtf8Array(payload.withCompression(CompressionType.UNCOMPRESSED).getData()); T configInstance = configPayload.toInstance(configClass, jrtRequest.getConfigKey().getConfigId()); - configInstance.setConfigMd5(jrtRequest.getNewConfigMd5()); + configInstance.setConfigMd5(jrtRequest.getNewConfigMd5()); // Note: Sets configmd5 in ConfigInstance return configInstance; } diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java index 992f59bdece..b7198b0c694 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java @@ -1,14 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription.impl; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; - import com.yahoo.config.ConfigInstance; import com.yahoo.config.ConfigurationRuntimeException; import com.yahoo.config.subscription.CfgConfigPayloadBuilder; @@ -18,6 +10,14 @@ import com.yahoo.io.IOUtils; import com.yahoo.vespa.config.ConfigKey; import com.yahoo.vespa.config.ConfigPayload; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; + /** * Subscription to use when config id is jar:.../foo.jar[!/pathInJar/] * @@ -63,7 +63,7 @@ public class JarConfigSubscription<T extends ConfigInstance> extends ConfigSubsc } catch (IOException e) { throw new ConfigurationRuntimeException(e); } - setConfig(0L, false, config); + setConfig(0L, false, config, PayloadChecksum.empty()); try { jarFile.close(); } catch (IOException e) { diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/PayloadChecksum.java b/config/src/main/java/com/yahoo/config/subscription/impl/PayloadChecksum.java new file mode 100644 index 00000000000..75e75e7b1f5 --- /dev/null +++ b/config/src/main/java/com/yahoo/config/subscription/impl/PayloadChecksum.java @@ -0,0 +1,48 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.subscription.impl; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Checksums of config definition payload or config payload, + * md5 and xxhash64 are the supported types at the moment. + * + * @author hmusum + */ +public class PayloadChecksum { + + private static final Pattern hexChecksumPattern = Pattern.compile("[0-9a-zA-Z]+"); + + private final String checksum; + private final Type type; + + public PayloadChecksum(String checksum) { + this.checksum = checksum; + this.type = Type.MD5; + } + + public static PayloadChecksum empty() { + return new PayloadChecksum(""); + } + + public String asString() { return checksum; } + + public Type type() { return type; } + + public enum Type {MD5, XXHASH64} + + public boolean valid() { + if (checksum.equals("")) return true; // Empty checksum is ok (e.g. when running 'vespa-get-config') + + if (type == Type.MD5 && checksum.length() != 32) { + return false; + } else if (type == Type.XXHASH64 && checksum.length() != 16) { + return false; + } + + Matcher m = hexChecksumPattern.matcher(checksum); + return m.matches(); + } + +} diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java index 68ff6bb0135..91b674da3d2 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java @@ -1,8 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.subscription.impl; -import java.util.Arrays; - import com.yahoo.config.ConfigInstance; import com.yahoo.config.subscription.CfgConfigPayloadBuilder; import com.yahoo.config.subscription.ConfigInterruptedException; @@ -10,6 +8,8 @@ import com.yahoo.config.subscription.ConfigSubscriber; import com.yahoo.vespa.config.ConfigKey; import com.yahoo.vespa.config.ConfigPayload; +import java.util.Arrays; + /** * Subscription used when config id is raw:... * <p> @@ -35,7 +35,7 @@ public class RawConfigSubscription<T extends ConfigInstance> extends ConfigSubsc if (payload == null) { payload = inputPayload; ConfigPayload configPayload = new CfgConfigPayloadBuilder().deserialize(Arrays.asList(payload.split("\n"))); - setConfig(0L, false, configPayload.toInstance(configClass, key.getConfigId())); + setConfig(0L, false, configPayload.toInstance(configClass, key.getConfigId()), PayloadChecksum.empty()); return true; } try { diff --git a/config/src/main/java/com/yahoo/vespa/config/ErrorCode.java b/config/src/main/java/com/yahoo/vespa/config/ErrorCode.java index 5fb99295325..3427dc7ddfd 100644 --- a/config/src/main/java/com/yahoo/vespa/config/ErrorCode.java +++ b/config/src/main/java/com/yahoo/vespa/config/ErrorCode.java @@ -11,6 +11,7 @@ public final class ErrorCode { public static final int UNKNOWN_DEFINITION = UNKNOWN_CONFIG + 1; public static final int UNKNOWN_DEF_MD5 = UNKNOWN_CONFIG + 4; public static final int UNKNOWN_VESPA_VERSION = UNKNOWN_CONFIG + 5; + public static final int UNKNOWN_DEF_CHECKSUM = UNKNOWN_CONFIG + 6; public static final int ILLEGAL_NAME = UNKNOWN_CONFIG + 100; // Version is not a number @@ -25,6 +26,8 @@ public final class ErrorCode { public static final int ILLEGAL_NAME_SPACE = UNKNOWN_CONFIG + 108; public static final int ILLEGAL_PROTOCOL_VERSION = UNKNOWN_CONFIG + 109; public static final int ILLEGAL_CLIENT_HOSTNAME = UNKNOWN_CONFIG + 110; + public static final int ILLEGAL_DEF_CHECKSUM = UNKNOWN_CONFIG + 111; + public static final int ILLEGAL_CONFIG_CHECKSUM = UNKNOWN_CONFIG + 112; // hasUpdatedConfig() is true, but generation says the config is older than previous config. public static final int OUTDATED_CONFIG = UNKNOWN_CONFIG + 150; diff --git a/config/src/main/java/com/yahoo/vespa/config/RawConfig.java b/config/src/main/java/com/yahoo/vespa/config/RawConfig.java index 1c28d4c5e05..366387f46af 100755 --- a/config/src/main/java/com/yahoo/vespa/config/RawConfig.java +++ b/config/src/main/java/com/yahoo/vespa/config/RawConfig.java @@ -140,7 +140,7 @@ public class RawConfig extends ConfigInstance { * @return true if this config is equal to the config in the given request. */ public boolean hasEqualConfig(JRTServerConfigRequest req) { - return (getConfigMd5().equals(req.getRequestConfigMd5())); + return getConfigMd5().equals(req.getRequestConfigMd5()); } /** diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java index 87e63399fc3..23e3259ff8b 100644 --- a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java +++ b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java @@ -110,11 +110,10 @@ public class JRTClientConfigRequestV3 implements JRTClientConfigRequest { CompressionType compressionType, Optional<VespaVersion> vespaVersion) { ConfigSubscription.ConfigState<T> configState = sub.getConfigState(); - T config = configState.getConfig(); return createWithParams(sub.getKey(), sub.getDefContent(), ConfigUtils.getCanonicalHostName(), - config != null ? config.getConfigMd5() : "", + configState.getChecksum().asString(), configState.getGeneration(), sub.timingValues().getSubscribeTimeout(), trace, diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/RequestValidation.java b/config/src/main/java/com/yahoo/vespa/config/protocol/RequestValidation.java index 478dc6c45d6..81ea99e38b4 100644 --- a/config/src/main/java/com/yahoo/vespa/config/protocol/RequestValidation.java +++ b/config/src/main/java/com/yahoo/vespa/config/protocol/RequestValidation.java @@ -1,13 +1,13 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.protocol; +import com.yahoo.config.subscription.impl.PayloadChecksum; import com.yahoo.vespa.config.ConfigDefinition; import com.yahoo.vespa.config.ConfigKey; import com.yahoo.vespa.config.ErrorCode; import java.util.logging.Logger; import java.util.regex.Matcher; -import java.util.regex.Pattern; import static java.util.logging.Level.INFO; @@ -19,8 +19,6 @@ import static java.util.logging.Level.INFO; public class RequestValidation { private static final Logger log = Logger.getLogger(RequestValidation.class.getName()); - private static final Pattern md5Pattern = Pattern.compile("[0-9a-zA-Z]+"); - public static int validateRequest(JRTConfigRequest request) { ConfigKey<?> key = request.getConfigKey(); if (!RequestValidation.verifyName(key.getName())) { @@ -31,13 +29,13 @@ public class RequestValidation { log.log(INFO, "Illegal name space '" + key.getNamespace() + "'"); return ErrorCode.ILLEGAL_NAME_SPACE; } - if (!RequestValidation.verifyMd5(key.getMd5())) { - log.log(INFO, "Illegal md5 sum '" + key.getNamespace() + "'"); - return ErrorCode.ILLEGAL_DEF_MD5; + if (!(new PayloadChecksum(key.getMd5()).valid())) { + log.log(INFO, "Illegal checksum '" + key.getNamespace() + "'"); + return ErrorCode.ILLEGAL_DEF_MD5; // TODO: Use ILLEGAL_DEF_CHECKSUM } - if (!RequestValidation.verifyMd5(request.getRequestConfigMd5())) { - log.log(INFO, "Illegal config md5 '" + request.getRequestConfigMd5() + "'"); - return ErrorCode.ILLEGAL_CONFIG_MD5; + if (!new PayloadChecksum(request.getRequestConfigMd5()).valid()) { + log.log(INFO, "Illegal config checksum '" + request.getRequestConfigMd5() + "'"); + return ErrorCode.ILLEGAL_CONFIG_MD5; // TODO: Use ILLEGAL_CONFIG_CHECKSUM } if (!RequestValidation.verifyGeneration(request.getRequestGeneration())) { log.log(INFO, "Illegal generation '" + request.getRequestGeneration() + "'"); @@ -59,16 +57,6 @@ public class RequestValidation { return m.matches(); } - public static boolean verifyMd5(String md5) { - if (md5.equals("")) { - return true; // Empty md5 is ok (e.g. upon getconfig from command line tools) - } else if (md5.length() != 32) { - return false; - } - Matcher m = md5Pattern.matcher(md5); - return m.matches(); - } - public static boolean verifyTimeout(Long timeout) { return (timeout > 0); } @@ -85,4 +73,5 @@ public class RequestValidation { private static boolean verifyHostname(String clientHostName) { return !("".equals(clientHostName)); } + } diff --git a/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java b/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java index bf516bee8a9..7bdaeb7d367 100644 --- a/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java @@ -139,7 +139,7 @@ public class JRTConfigRequesterTest { ConfigSubscriber subscriber = new ConfigSubscriber(); final TimingValues timingValues = getTestTimingValues(); JRTConfigSubscription<SimpletypesConfig> sub = createSubscription(subscriber, timingValues); - sub.setConfig(1L, false, config()); + sub.setConfig(1L, false, config(), PayloadChecksum.empty()); final MockConnection connection = new MockConnection(new ErrorResponseHandler()); JRTConfigRequester requester = new JRTConfigRequester(connection, timingValues); @@ -165,7 +165,7 @@ public class JRTConfigRequesterTest { ConfigSubscriber subscriber = new ConfigSubscriber(); final TimingValues timingValues = getTestTimingValues(); JRTConfigSubscription<SimpletypesConfig> sub = createSubscription(subscriber, timingValues); - sub.setConfig(1L, false, config()); + sub.setConfig(1L, false, config(), PayloadChecksum.empty()); final MockConnection connection = new MockConnection(new ErrorResponseHandler(com.yahoo.jrt.ErrorCode.TIMEOUT)); JRTConfigRequester requester = new JRTConfigRequester(connection, timingValues); @@ -179,7 +179,7 @@ public class JRTConfigRequesterTest { ConfigSubscriber subscriber = new ConfigSubscriber(); final TimingValues timingValues = getTestTimingValues(); JRTConfigSubscription<SimpletypesConfig> sub = createSubscription(subscriber, timingValues); - sub.setConfig(1L, false, config()); + sub.setConfig(1L, false, config(), PayloadChecksum.empty()); final MockConnection connection = new MockConnection(new ErrorResponseHandler(ErrorCode.UNKNOWN_DEFINITION)); JRTConfigRequester requester = new JRTConfigRequester(connection, timingValues); diff --git a/config/src/test/java/com/yahoo/vespa/config/RequestValidationTest.java b/config/src/test/java/com/yahoo/vespa/config/RequestValidationTest.java index 3f625013f27..8c11db15f7c 100644 --- a/config/src/test/java/com/yahoo/vespa/config/RequestValidationTest.java +++ b/config/src/test/java/com/yahoo/vespa/config/RequestValidationTest.java @@ -1,6 +1,7 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config; +import com.yahoo.config.subscription.impl.PayloadChecksum; import com.yahoo.vespa.config.protocol.RequestValidation; import org.junit.Test; @@ -20,11 +21,11 @@ public class RequestValidationTest { @Test public void testVerifyDefMd5() { - assertTrue(RequestValidation.verifyMd5("")); - assertTrue(RequestValidation.verifyMd5("e8f0c01c7c3dcb8d3f62d7ff777fce6b")); - assertTrue(RequestValidation.verifyMd5("e8f0c01c7c3dcb8d3f62d7ff777fce6B")); - assertFalse(RequestValidation.verifyMd5("aaaaaaaaaaaaaaaaaa")); - assertFalse(RequestValidation.verifyMd5("-8f0c01c7c3dcb8d3f62d7ff777fce6b")); + assertTrue(PayloadChecksum.empty().valid()); + assertTrue(new PayloadChecksum("e8f0c01c7c3dcb8d3f62d7ff777fce6b").valid()); + assertTrue(new PayloadChecksum("e8f0c01c7c3dcb8d3f62d7ff777fce6B").valid()); + assertFalse(new PayloadChecksum("aaaaaaaaaaaaaaaaaa").valid()); + assertFalse(new PayloadChecksum("-8f0c01c7c3dcb8d3f62d7ff777fce6b").valid()); } @Test @@ -32,4 +33,5 @@ public class RequestValidationTest { assertTrue(RequestValidation.verifyTimeout(1000L)); assertFalse(RequestValidation.verifyTimeout(-1000L)); } + } diff --git a/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java b/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java index 006a6fc6a0a..b67a9ef0fb8 100644 --- a/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java +++ b/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.protocol; import com.yahoo.config.subscription.ConfigSet; @@ -201,8 +201,7 @@ public class JRTConfigRequestV3Test { assertTrue(sub.nextConfig(120_0000)); sub.close(); JRTClientConfigRequest nextReq = createReq(sub, Trace.createNew()); - SimpletypesConfig config = sub.getConfigState().getConfig(); - assertThat(nextReq.getRequestConfigMd5(), is(config.getConfigMd5())); + assertThat(nextReq.getRequestConfigMd5(), is(sub.getConfigState().getChecksum().asString())); assertThat(nextReq.getRequestGeneration(), is(currentGeneration)); } diff --git a/dist/vespa.spec b/dist/vespa.spec index e1cbca206f5..6e4db510929 100644 --- a/dist/vespa.spec +++ b/dist/vespa.spec @@ -281,8 +281,9 @@ Requires: %{name}-malloc = %{version}-%{release} Requires: %{name}-tools = %{version}-%{release} # Ugly workaround because vespamalloc/src/vespamalloc/malloc/mmap.cpp uses the private -# _dl_sym function. Exclude automated reqires for libraries in /opt/vespa-deps/lib64. -%global __requires_exclude ^lib(c\\.so\\.6\\(GLIBC_PRIVATE\\)|pthread\\.so\\.0\\(GLIBC_PRIVATE\\)|(crypto|icui18n|icuuc|lz4|protobuf|ssl|zstd|onnxruntime%{?_use_vespa_openblas:|openblas}%{?_use_vespa_re2:|re2}%{?_use_vespa_xxhash:|xxhash})\\.so\\.[0-9.]*\\([A-Z._0-9]*\\))\\(64bit\\)$ +# _dl_sym function. +# Exclude automated requires for libraries in /opt/vespa-deps/lib64. +%global __requires_exclude ^lib(c\\.so\\.6\\(GLIBC_PRIVATE\\)|pthread\\.so\\.0\\(GLIBC_PRIVATE\\)|(crypto|icui18n|icuuc|lz4|protobuf|ssl|zstd|onnxruntime%{?_use_vespa_openblas:|openblas}%{?_use_vespa_re2:|re2}%{?_use_vespa_xxhash:|xxhash})\\.so\\.[0-9.]*\\([A-Za-z._0-9]*\\))\\(64bit\\)$ %description diff --git a/eval/src/apps/eval_expr/eval_expr.cpp b/eval/src/apps/eval_expr/eval_expr.cpp index 19e7369414e..ce2efd52ed1 100644 --- a/eval/src/apps/eval_expr/eval_expr.cpp +++ b/eval/src/apps/eval_expr/eval_expr.cpp @@ -31,6 +31,16 @@ using vespalib::slime::Cursor; const auto &factory = FastValueBuilderFactory::get(); +void list_commands(FILE *file, const char *prefix) { + fprintf(file, "%s'exit' -> exit the program\n", prefix); + fprintf(file, "%s'help' -> print available commands\n", prefix); + fprintf(file, "%s'list' -> list named values\n", prefix); + fprintf(file, "%s'verbose (true|false)' -> enable or disable verbose output\n", prefix); + fprintf(file, "%s'def <name> <expr>' -> evaluate expression, bind result to a name\n", prefix); + fprintf(file, "%s'undef <name>' -> remove a named value\n", prefix); + fprintf(file, "%s'<expr>' -> evaluate expression\n", prefix); +} + int usage(const char *self) { // ------------------------------------------------------------------------------- fprintf(stderr, "usage: %s [--verbose] <expr> [expr ...]\n", self); @@ -47,12 +57,7 @@ int usage(const char *self) { fprintf(stderr, "\n"); fprintf(stderr, "advanced usage: %s interactive\n", self); fprintf(stderr, " This runs the progam in interactive mode. possible commands (line based):\n"); - fprintf(stderr, " 'exit' -> exit the program\n"); - fprintf(stderr, " 'help' -> print available commands\n"); - fprintf(stderr, " 'list' -> list named values\n"); - fprintf(stderr, " 'verbose (true|false)' -> enable or disable verbose output\n"); - fprintf(stderr, " 'def <name> <expr>' -> evaluate expression, bind result to a name\n"); - fprintf(stderr, " '<expr>' -> evaluate expression\n"); + list_commands(stderr, " "); fprintf(stderr, "\n"); fprintf(stderr, "advanced usage: %s json-repl\n", self); fprintf(stderr, " This will put the program into a read-eval-print loop where it reads\n"); @@ -150,6 +155,19 @@ public: _param_values.push_back(std::move(value)); _param_refs.emplace_back(*_param_values.back()); } + + bool remove(const vespalib::string &name) { + for (size_t i = 0; i < _param_names.size(); ++i) { + if (_param_names[i] == name) { + _param_names.erase(_param_names.begin() + i); + _param_types.erase(_param_types.begin() + i); + _param_values.erase(_param_values.begin() + i); + _param_refs.erase(_param_refs.begin() + i); + return true; + } + } + return false; + } }; Context::~Context() = default; @@ -264,6 +282,7 @@ const vespalib::string help_cmd("help"); const vespalib::string list_cmd("list"); const vespalib::string verbose_cmd("verbose "); const vespalib::string def_cmd("def "); +const vespalib::string undef_cmd("undef "); int interactive_mode(Context &ctx) { EditLineWrapper input; @@ -273,12 +292,7 @@ int interactive_mode(Context &ctx) { return 0; } if (line == help_cmd) { - fprintf(stdout, " 'exit' -> exit the program\n"); - fprintf(stdout, " 'help' -> print available commands\n"); - fprintf(stdout, " 'list' -> list named values\n"); - fprintf(stdout, " 'verbose (true|false)' -> enable or disable verbose output\n"); - fprintf(stdout, " 'def <name> <expr>' -> evaluate expression, bind result to a name\n"); - fprintf(stdout, " '<expr>' -> evaluate expression\n"); + list_commands(stdout, " "); continue; } if (line == list_cmd) { @@ -299,8 +313,17 @@ int interactive_mode(Context &ctx) { } continue; } - vespalib::string expr; vespalib::string name; + if (line.find(undef_cmd) == 0) { + name = line.substr(undef_cmd.size()); + if (ctx.remove(name)) { + fprintf(stdout, "removed value '%s'\n", name.c_str()); + } else { + fprintf(stdout, "value not found: '%s'\n", name.c_str()); + } + continue; + } + vespalib::string expr; if (line.find(def_cmd) == 0) { auto name_size = (line.find(" ", def_cmd.size()) - def_cmd.size()); name = line.substr(def_cmd.size(), name_size); diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index e030edc4565..3eef6be7012 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -190,22 +190,22 @@ public class Flags { ZONE_ID, APPLICATION_ID); public static final UnboundBooleanFlag USE_EXTERNAL_RANK_EXPRESSION = defineFeatureFlag( - "use-external-rank-expression", false, - List.of("baldersheim"), "2021-05-24", "2021-09-01", + "use-external-rank-expression", true, + List.of("baldersheim"), "2021-05-24", "2021-09-15", "Whether to use distributed external rank expression or inline in rankproperties", "Takes effect on next internal redeployment", APPLICATION_ID); public static final UnboundBooleanFlag DISTRIBUTE_EXTERNAL_RANK_EXPRESSION = defineFeatureFlag( "distribute-external-rank-expression", false, - List.of("baldersheim"), "2021-05-27", "2021-09-01", + List.of("baldersheim"), "2021-05-27", "2021-09-15", "Whether to use distributed external rank expression files by filedistribution", "Takes effect on next internal redeployment", APPLICATION_ID); public static final UnboundIntFlag LARGE_RANK_EXPRESSION_LIMIT = defineIntFlag( - "large-rank-expression-limit", 0x10000, - List.of("baldersheim"), "2021-06-09", "2021-09-01", + "large-rank-expression-limit", 8192, + List.of("baldersheim"), "2021-06-09", "2021-09-15", "Limit for size of rank expressions distributed by filedistribution", "Takes effect on next internal redeployment", APPLICATION_ID); @@ -225,7 +225,7 @@ public class Flags { public static final UnboundBooleanFlag THROW_EXCEPTION_IF_RESOURCE_LIMITS_SPECIFIED = defineFeatureFlag( "throw-exception-if-resource-limits-specified", false, - List.of("hmusum"), "2021-06-07", "2021-09-07", + List.of("hmusum"), "2021-06-07", "2021-09-15", "Whether to throw an exception in hosted Vespa if the application specifies resource limits in services.xml", "Takes effect on next deployment through controller", APPLICATION_ID); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java index b799e0056f3..2db645a67b3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/AllocatableClusterResources.java @@ -43,10 +43,10 @@ public class AllocatableClusterResources { this.fulfilment = 1; } - public AllocatableClusterResources(List<Node> nodes, NodeRepository nodeRepository, boolean exclusive) { + public AllocatableClusterResources(List<Node> nodes, NodeRepository nodeRepository) { this.nodes = nodes.size(); this.groups = (int)nodes.stream().map(node -> node.allocation().get().membership().cluster().group()).distinct().count(); - this.realResources = averageRealResourcesOf(nodes, nodeRepository, exclusive); // Average since we average metrics over nodes + this.realResources = averageRealResourcesOf(nodes, nodeRepository); // Average since we average metrics over nodes this.advertisedResources = nodes.get(0).allocation().get().requestedResources(); this.clusterSpec = nodes.get(0).allocation().get().membership().cluster(); this.fulfilment = 1; @@ -124,10 +124,10 @@ public class AllocatableClusterResources { (fulfilment < 1.0 ? " (fulfilment " + fulfilment + ")" : ""); } - private static NodeResources averageRealResourcesOf(List<Node> nodes, NodeRepository nodeRepository, boolean exclusive) { + private static NodeResources averageRealResourcesOf(List<Node> nodes, NodeRepository nodeRepository) { NodeResources sum = new NodeResources(0, 0, 0, 0); for (Node node : nodes) - sum = sum.add(nodeRepository.resourcesCalculator().realResourcesOf(node, nodeRepository, exclusive).justNumbers()); + sum = sum.add(nodeRepository.resourcesCalculator().realResourcesOf(node, nodeRepository).justNumbers()); return nodes.get(0).allocation().get().requestedResources().justNonNumbers() .withVcpu(sum.vcpu() / nodes.size()) .withMemoryGb(sum.memoryGb() / nodes.size()) diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java index ccaf23c49ed..836b256a1b3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/Autoscaler.java @@ -85,7 +85,7 @@ public class Autoscaler { "Have measurements from " + clusterModel.nodeTimeseries().nodesMeasured() + " nodes, but require from " + clusterNodes.size()); - var currentAllocation = new AllocatableClusterResources(clusterNodes.asList(), nodeRepository, cluster.exclusive()); + var currentAllocation = new AllocatableClusterResources(clusterNodes.asList(), nodeRepository); var target = ResourceTarget.idealLoad(clusterModel, currentAllocation); Optional<AllocatableClusterResources> bestAllocation = diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java index 3914a0c9f07..6f617e9ff23 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java @@ -82,7 +82,7 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer { applications().put(application.get().with(updatedCluster), lock); if (advice.isPresent() && advice.target().isPresent() && !cluster.get().targetResources().equals(advice.target())) { // 2. Also autoscale - logAutoscaling(advice.target().get(), applicationId, updatedCluster, clusterNodes); + logAutoscaling(advice.target().get(), applicationId, clusterNodes); try (MaintenanceDeployment deployment = new MaintenanceDeployment(applicationId, deployer, metric, nodeRepository())) { if (deployment.isValid()) deployment.activate(); @@ -121,11 +121,8 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer { return cluster.with(event.withCompletion(completionTime)); } - private void logAutoscaling(ClusterResources target, - ApplicationId application, - Cluster cluster, - NodeList clusterNodes) { - ClusterResources current = new AllocatableClusterResources(clusterNodes.asList(), nodeRepository(), cluster.exclusive()).advertisedResources(); + private void logAutoscaling(ClusterResources target, ApplicationId application, NodeList clusterNodes) { + ClusterResources current = new AllocatableClusterResources(clusterNodes.asList(), nodeRepository()).advertisedResources(); log.info("Autoscaling " + application + " " + clusterNodes.clusterSpec() + ":" + "\nfrom " + toString(current) + "\nto " + toString(target)); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java index 599f6b8bcb0..fa86fd9a29e 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/EmptyProvisionServiceProvider.java @@ -35,7 +35,7 @@ public class EmptyProvisionServiceProvider implements ProvisionServiceProvider { private static class IdentityHostResourcesCalculator implements HostResourcesCalculator { @Override - public NodeResources realResourcesOf(Nodelike node, NodeRepository repository, boolean exclusive) { return node.resources(); } + public NodeResources realResourcesOf(Nodelike node, NodeRepository repository) { return node.resources(); } @Override public NodeResources advertisedResourcesOf(Flavor flavor) { return flavor.resources(); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java index fc7023be743..92d7ba95604 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostResourcesCalculator.java @@ -19,7 +19,7 @@ import com.yahoo.vespa.hosted.provision.Nodelike; public interface HostResourcesCalculator { /** Returns the real resources available on a node */ - NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository, boolean exclusive); + NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository); /** Returns the advertised resources of a flavor */ NodeResources advertisedResourcesOf(Flavor flavor); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java index 24d23f13bb5..74f354feb30 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java @@ -161,7 +161,7 @@ public class NodeRepositoryProvisioner implements Provisioner { AllocatableClusterResources currentResources = firstDeployment // start at min, preserve current resources otherwise ? new AllocatableClusterResources(requested.minResources(), clusterSpec, nodeRepository) - : new AllocatableClusterResources(nodes.asList(), nodeRepository, clusterSpec.isExclusive()); + : new AllocatableClusterResources(nodes.asList(), nodeRepository); var clusterModel = new ClusterModel(application, cluster, clusterSpec, nodes, nodeRepository.metricsDb(), nodeRepository.clock()); return within(Limits.of(requested), currentResources, firstDeployment, clusterModel); } @@ -199,7 +199,7 @@ public class NodeRepositoryProvisioner implements Provisioner { log.log(Level.FINE, () -> "Prepared node " + node.hostname() + " - " + node.flavor()); Allocation nodeAllocation = node.allocation().orElseThrow(IllegalStateException::new); hosts.add(new HostSpec(node.hostname(), - nodeRepository.resourcesCalculator().realResourcesOf(node, nodeRepository, node.allocation().get().membership().cluster().isExclusive()), + nodeRepository.resourcesCalculator().realResourcesOf(node, nodeRepository), node.flavor().resources(), requestedResources, nodeAllocation.membership(), diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java index 0b007bf4a41..2dbb17dfd9a 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceLimits.java @@ -41,10 +41,7 @@ public class NodeResourceLimits { /** Returns whether the real resources we'll end up with on a given tenant node are within limits */ public boolean isWithinRealLimits(NodeCandidate candidateNode, ClusterSpec cluster) { if (candidateNode.type() != NodeType.tenant) return true; // Resource limits only apply to tenant nodes - // This node is allocated exclusively if that has been explicitly requested, or if the host of the node was - // provisioned exclusively - boolean exclusive = cluster.isExclusive() || candidateNode.parent.flatMap(Node::exclusiveToApplicationId).isPresent(); - return isWithinRealLimits(nodeRepository.resourcesCalculator().realResourcesOf(candidateNode, nodeRepository, exclusive), + return isWithinRealLimits(nodeRepository.resourcesCalculator().realResourcesOf(candidateNode, nodeRepository), cluster.type()); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java index 53b6a91d962..2cf671514c4 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java @@ -5,6 +5,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.DockerImage; import com.yahoo.config.provision.Flavor; +import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.serialization.NetworkPortsSerializer; import com.yahoo.container.jdisc.HttpRequest; @@ -115,8 +116,9 @@ class NodesResponse extends SlimeJsonResponse { toSlime(node, true, object); } - @SuppressWarnings("deprecation") private void toSlime(Node node, boolean allFields, Cursor object) { + NodeResources realResources = nodeRepository.resourcesCalculator().realResourcesOf(node, nodeRepository); + object.setString("url", nodeParentUrl + node.hostname()); if ( ! allFields) return; object.setString("id", node.hostname()); @@ -134,6 +136,7 @@ class NodesResponse extends SlimeJsonResponse { if (node.flavor().isConfigured()) object.setDouble("cpuCores", node.flavor().resources().vcpu()); NodeResourcesSerializer.toSlime(node.flavor().resources(), object.setObject("resources")); + NodeResourcesSerializer.toSlime(realResources, object.setObject("realResources")); if (node.flavor().cost() > 0) object.setLong("cost", node.flavor().cost()); object.setString("environment", node.flavor().getType().name()); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java index d65ae143487..b062c0f9135 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTest.java @@ -4,7 +4,6 @@ package com.yahoo.vespa.hosted.provision.autoscale; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.Capacity; import com.yahoo.config.provision.Cloud; -import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.ClusterResources; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Environment; @@ -747,7 +746,7 @@ public class AutoscalingTest { } @Override - public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository, boolean exclusive) { + public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository) { return node.resources(); } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java index 1902d762fb4..8dbaad13fc9 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/autoscale/AutoscalingTester.java @@ -28,8 +28,6 @@ import com.yahoo.vespa.hosted.provision.provisioning.HostResourcesCalculator; import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester; import java.time.Duration; -import java.time.Instant; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -362,7 +360,7 @@ class AutoscalingTester { } @Override - public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository, boolean exclusive) { + public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository) { if (zone.getCloud().dynamicProvisioning()) return node.resources().withMemoryGb(node.resources().memoryGb() - 3); else diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java index 45cafc3e5cc..fa68533bb06 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java @@ -744,7 +744,7 @@ public class ProvisioningTester { } @Override - public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository, boolean exclusive) { + public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository) { NodeResources resources = node.resources(); if (node.type() == NodeType.host) return resources; return resources.withMemoryGb(resources.memoryGb() - memoryTaxGb) diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningCompleteHostCalculatorTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningCompleteHostCalculatorTest.java index 5f2d567bd24..03a7d56b03c 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningCompleteHostCalculatorTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningCompleteHostCalculatorTest.java @@ -81,7 +81,7 @@ public class VirtualNodeProvisioningCompleteHostCalculatorTest { } @Override - public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository, boolean exclusive) { + public NodeResources realResourcesOf(Nodelike node, NodeRepository nodeRepository) { if (node.parentHostname().isEmpty()) return node.resources(); // hosts use configured flavors return realResourcesOf(node.resources()); } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg1.json index 87fa1b15d84..fb2b32fac20 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg1.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg1.json @@ -8,6 +8,7 @@ "flavor": "default", "cpuCores": 2.0, "resources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg2.json index ed95343586b..eccde886d7e 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/cfg2.json @@ -8,6 +8,7 @@ "flavor": "default", "cpuCores": 2.0, "resources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/controller1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/controller1.json index a4a71e0f48b..1631e46fc32 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/controller1.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/controller1.json @@ -8,6 +8,7 @@ "flavor": "default", "cpuCores": 2.0, "resources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-container1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-container1.json index 4f8dd0ade37..6be127315e2 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-container1.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-container1.json @@ -8,6 +8,7 @@ "openStackId": "fake-test-node-pool-102-2", "flavor": "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, storage type: remote]", "resources":{"vcpu":1.0,"memoryGb":4.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":1.0,"memoryGb":4.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant3", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-os-upgrade-complete.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-os-upgrade-complete.json index cf395653a42..cc9f8c7c58f 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-os-upgrade-complete.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-os-upgrade-complete.json @@ -8,6 +8,7 @@ "flavor": "large", "cpuCores": 4.0, "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-2.json index 98f9c9b245e..f9dd810902c 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-2.json @@ -7,14 +7,8 @@ "openStackId": "dockerhost1", "flavor": "large", "cpuCores": 4.0, - "resources": { - "vcpu": 4.0, - "memoryGb": 32.0, - "diskGb": 1600.0, - "bandwidthGbps": 20.0, - "diskSpeed": "fast", - "storageType": "remote" - }, + "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-3.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-3.json index fe56b7ae711..74d402de796 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-3.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-3.json @@ -7,14 +7,8 @@ "openStackId": "dockerhost1", "flavor": "large", "cpuCores": 4.0, - "resources": { - "vcpu": 4.0, - "memoryGb": 32.0, - "diskGb": 1600.0, - "bandwidthGbps": 20.0, - "diskSpeed": "fast", - "storageType": "remote" - }, + "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-4.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-4.json index ca1944b661d..b1d8c5fba9a 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-4.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports-4.json @@ -7,14 +7,8 @@ "openStackId": "dockerhost1", "flavor": "large", "cpuCores": 4.0, - "resources": { - "vcpu": 4.0, - "memoryGb": 32.0, - "diskGb": 1600.0, - "bandwidthGbps": 20.0, - "diskSpeed": "fast", - "storageType": "remote" - }, + "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports.json index dda664f52c6..660e67796f9 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1-reports.json @@ -7,14 +7,8 @@ "openStackId": "dockerhost1", "flavor": "large", "cpuCores": 4.0, - "resources": { - "vcpu": 4.0, - "memoryGb": 32.0, - "diskGb": 1600.0, - "bandwidthGbps": 20.0, - "diskSpeed": "fast", - "storageType": "remote" - }, + "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1.json index 5a897527077..b8397cfb6af 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node1.json @@ -8,6 +8,7 @@ "flavor": "large", "cpuCores": 4.0, "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json index 35b778b08d0..60d194163b7 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node2.json @@ -8,6 +8,7 @@ "flavor": "large", "cpuCores": 4.0, "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node3.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node3.json index 0ff0747cc43..58db8d47bcc 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node3.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node3.json @@ -8,6 +8,7 @@ "flavor": "large", "cpuCores": 4.0, "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node4.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node4.json index 6e085066c9f..b5ddc4d99a8 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node4.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node4.json @@ -8,6 +8,7 @@ "flavor": "large", "cpuCores": 4.0, "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node5.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node5.json index b15e748084e..8f4c91282ca 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node5.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/docker-node5.json @@ -8,6 +8,7 @@ "flavor": "large", "cpuCores": 4.0, "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost1-with-firmware-data.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost1-with-firmware-data.json index 2f58fadd187..866efefc1d3 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost1-with-firmware-data.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost1-with-firmware-data.json @@ -8,6 +8,7 @@ "flavor": "large", "cpuCores": 4.0, "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "owner": { "tenant": "zoneapp", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost6.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost6.json index 68da9b9427d..1ba16743e25 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost6.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/dockerhost6.json @@ -7,14 +7,8 @@ "openStackId": "dockerhost6", "flavor": "large", "cpuCores": 4.0, - "resources": { - "vcpu": 4.0, - "memoryGb": 32.0, - "diskGb": 1600.0, - "bandwidthGbps": 20.0, - "diskSpeed": "fast", - "storageType": "remote" - }, + "resources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":4.0,"memoryGb":32.0,"diskGb":1600.0,"bandwidthGbps":20.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node1.json index 0eec239f7dc..32ed54452de 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node1.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node1.json @@ -7,6 +7,7 @@ "openStackId": "node1", "flavor": "[vcpu: 2.0, memory: 8.0 Gb, disk 50.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant1", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node10.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node10.json index bc101402725..624976414da 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node10.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node10.json @@ -8,6 +8,7 @@ "openStackId": "node10", "flavor": "[vcpu: 2.0, memory: 8.0 Gb, disk 50.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant1", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node11.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node11.json index 4e6ae69de38..4cfb5ac8e78 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node11.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node11.json @@ -8,6 +8,7 @@ "openStackId": "host11.yahoo.com", "flavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb, bandwidth: 0.3 Gbps]", "resources":{"vcpu":1.0,"memoryGb":1.0,"diskGb":100.0,"bandwidthGbps":0.3,"diskSpeed":"fast","storageType":"any"}, + "realResources":{"vcpu":1.0,"memoryGb":1.0,"diskGb":100.0,"bandwidthGbps":0.3,"diskSpeed":"fast","storageType":"any"}, "environment": "DOCKER_CONTAINER", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node13.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node13.json index 96ff3eab48d..f3feaea4d3a 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node13.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node13.json @@ -7,6 +7,7 @@ "openStackId": "node13", "flavor": "[vcpu: 10.0, memory: 48.0 Gb, disk 500.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":10.0,"memoryGb":48.0,"diskGb":500.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":10.0,"memoryGb":48.0,"diskGb":500.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant4", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node14.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node14.json index eb58f5fd928..cd71055c3e2 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node14.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node14.json @@ -7,6 +7,7 @@ "openStackId": "node14", "flavor": "[vcpu: 10.0, memory: 48.0 Gb, disk 500.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":10.0,"memoryGb":48.0,"diskGb":500.0,"bandwidthGbps":1.0, "diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":10.0,"memoryGb":48.0,"diskGb":500.0,"bandwidthGbps":1.0, "diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant4", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node2.json index 73f9cabba17..f544436159c 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node2.json @@ -7,6 +7,7 @@ "openStackId": "node2", "flavor": "[vcpu: 2.0, memory: 8.0 Gb, disk 50.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant2", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json index 9997478d8bb..ac3e9ef96b0 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node3.json @@ -7,6 +7,7 @@ "openStackId": "node3", "flavor": "[vcpu: 0.5, memory: 48.0 Gb, disk 500.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":0.5,"memoryGb":48.0,"diskGb":500.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":0.5,"memoryGb":48.0,"diskGb":500.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-after-changes.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-after-changes.json index 04d4cdfa505..7298f4737fe 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-after-changes.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-after-changes.json @@ -9,6 +9,7 @@ "flavor": "d-2-8-100", "cpuCores": 2.0, "resources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant3", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-with-hostnames.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-with-hostnames.json index e6c2ba350d2..603b7f22bb3 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-with-hostnames.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4-with-hostnames.json @@ -8,6 +8,7 @@ "openStackId": "node4", "flavor": "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":1.0,"memoryGb":4.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":1.0,"memoryGb":4.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant3", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4.json index 1ae403bcba6..ba9e58bdcba 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node4.json @@ -8,6 +8,7 @@ "openStackId": "node4", "flavor": "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":1.0,"memoryGb":4.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":1.0,"memoryGb":4.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant3", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5-after-changes.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5-after-changes.json index 35c2ee570c8..62ecb313588 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5-after-changes.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5-after-changes.json @@ -8,6 +8,7 @@ "openStackId": "node5", "flavor": "[vcpu: 1.0, memory: 8.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, disk speed: slow, storage type: remote]", "resources":{"vcpu":1.0,"memoryGb":8.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"slow","storageType":"remote"}, + "realResources":{"vcpu":1.0,"memoryGb":8.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"slow","storageType":"remote"}, "environment": "DOCKER_CONTAINER", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5.json index a45bf4a0c53..55c16c23a0a 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node5.json @@ -8,6 +8,7 @@ "openStackId": "node5", "flavor": "[vcpu: 1.0, memory: 8.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, disk speed: slow, storage type: remote]", "resources":{"vcpu":1.0,"memoryGb":8.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"slow","storageType":"remote"}, + "realResources":{"vcpu":1.0,"memoryGb":8.0,"diskGb":100.0,"bandwidthGbps":1.0,"diskSpeed":"slow","storageType":"remote"}, "environment": "DOCKER_CONTAINER", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node55.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node55.json index 9ccb0f1c1f4..2ac665bf742 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node55.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node55.json @@ -7,6 +7,7 @@ "openStackId": "node55", "flavor": "[vcpu: 2.0, memory: 8.0 Gb, disk 50.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node6.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node6.json index a6eede0675c..f4dbf657926 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node6.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node6.json @@ -7,6 +7,7 @@ "openStackId": "node6", "flavor": "[vcpu: 2.0, memory: 8.0 Gb, disk 50.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "owner": { "tenant": "tenant2", diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node7.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node7.json index 289e37f6aeb..051325612d6 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node7.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node7.json @@ -7,6 +7,7 @@ "openStackId": "node7", "flavor": "[vcpu: 2.0, memory: 8.0 Gb, disk 50.0 Gb, bandwidth: 1.0 Gbps, storage type: local]", "resources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, + "realResources":{"vcpu":2.0,"memoryGb":8.0,"diskGb":50.0,"bandwidthGbps":1.0,"diskSpeed":"fast","storageType":"local"}, "environment": "DOCKER_CONTAINER", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node8.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node8.json index e270b10a753..11eb5149fbc 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node8.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node8.json @@ -8,6 +8,7 @@ "flavor": "default", "cpuCores": 2.0, "resources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType": "remote"}, + "realResources":{"vcpu":2.0,"memoryGb":16.0,"diskGb":400.0,"bandwidthGbps":10.0,"diskSpeed":"fast","storageType": "remote"}, "environment": "BARE_METAL", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node9.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node9.json index 7a69f51f2e4..a1eb16195d2 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node9.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/node9.json @@ -8,6 +8,7 @@ "flavor": "large-variant", "cpuCores": 64.0, "resources":{"vcpu":64.0,"memoryGb":128.0,"diskGb":2000.0,"bandwidthGbps":15.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources":{"vcpu":64.0,"memoryGb":128.0,"diskGb":2000.0,"bandwidthGbps":15.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/parent2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/parent2.json index cf53435a860..acf481cd9c9 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/parent2.json +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/parent2.json @@ -10,6 +10,7 @@ "exclusiveTo": "tenant1:app1:instance1", "cpuCores": 64.0, "resources": {"vcpu":64.0,"memoryGb":128.0,"diskGb":2000.0,"bandwidthGbps":15.0,"diskSpeed":"fast","storageType":"remote"}, + "realResources": {"vcpu":64.0,"memoryGb":128.0,"diskGb":2000.0,"bandwidthGbps":15.0,"diskSpeed":"fast","storageType":"remote"}, "environment": "BARE_METAL", "rebootGeneration": 0, "currentRebootGeneration": 0, diff --git a/storageserver/src/vespa/storageserver/app/distributorprocess.cpp b/storageserver/src/vespa/storageserver/app/distributorprocess.cpp index 45802df8866..9b66500cef4 100644 --- a/storageserver/src/vespa/storageserver/app/distributorprocess.cpp +++ b/storageserver/src/vespa/storageserver/app/distributorprocess.cpp @@ -56,7 +56,7 @@ DistributorProcess::setupConfig(milliseconds subscribeTimeout) auto distr_cfg = config::ConfigGetter<StorDistributormanagerConfig>::getConfig( _configUri.getConfigId(), _configUri.getContext(), subscribeTimeout); - _num_distributor_stripes = adjusted_num_distributor_stripes(distr_cfg->numDistributorStripes); + _num_distributor_stripes = adjusted_num_distributor_stripes(std::max(distr_cfg->numDistributorStripes, 0)); _distributorConfigHandler = _configSubscriber.subscribe<StorDistributormanagerConfig>(_configUri.getConfigId(), subscribeTimeout); _visitDispatcherConfigHandler = _configSubscriber.subscribe<StorVisitordispatcherConfig>(_configUri.getConfigId(), subscribeTimeout); Process::setupConfig(subscribeTimeout); |