diff --git a/cmd/jujuc/main_test.go b/cmd/jujuc/main_test.go index f34f1eda2a2..7ecd12e95e8 100644 --- a/cmd/jujuc/main_test.go +++ b/cmd/jujuc/main_test.go @@ -105,6 +105,8 @@ func run(c *gc.C, sockPath sockets.Socket, contextId string, exit int, stdin []b fmt.Sprintf("JUJU_AGENT_SOCKET_ADDRESS=%s", sockPath.Address), fmt.Sprintf("JUJU_AGENT_SOCKET_NETWORK=%s", sockPath.Network), fmt.Sprintf("JUJU_CONTEXT_ID=%s", contextId), + // See: https://go.dev/doc/build-cover + fmt.Sprintf("GOCOVERDIR=%s", ps.Dir), // Code that imports github.com/juju/juju/testing needs to // be able to find that module at runtime (via build.Import), // so we have to preserve that env variable. @@ -203,5 +205,5 @@ func (s *HookToolMainSuite) TestBadSockPath(c *gc.C) { func (s *HookToolMainSuite) TestStdin(c *gc.C) { output := run(c, s.sockPath, "bill", 0, []byte("some standard input"), "remote") - c.Assert(output, gc.Equals, "some standard input") + c.Assert(output, jc.Contains, "some standard input") } diff --git a/cmd/jujud/main_test.go b/cmd/jujud/main_test.go index 8839d3f8be9..37aa82220e8 100644 --- a/cmd/jujud/main_test.go +++ b/cmd/jujud/main_test.go @@ -157,6 +157,8 @@ func runForTest(c *gc.C, sockPath sockets.Socket, contextId string, exit int, st fmt.Sprintf("JUJU_AGENT_SOCKET_ADDRESS=%s", sockPath.Address), fmt.Sprintf("JUJU_AGENT_SOCKET_NETWORK=%s", sockPath.Network), fmt.Sprintf("JUJU_CONTEXT_ID=%s", contextId), + // See: https://go.dev/doc/build-cover + fmt.Sprintf("GOCOVERDIR=%s", ps.Dir), // Code that imports github.com/juju/juju/testing needs to // be able to find that module at runtime (via build.Import), // so we have to preserve that env variable. @@ -255,5 +257,5 @@ func (s *HookToolMainSuite) TestBadSockPath(c *gc.C) { func (s *HookToolMainSuite) TestStdin(c *gc.C) { output := runForTest(c, s.sockPath, "bill", 0, []byte("some standard input"), "remote") - c.Assert(output, gc.Equals, "some standard input") + c.Assert(output, jc.Contains, "some standard input") } diff --git a/environs/config/config.go b/environs/config/config.go index 55edd19e8f9..f92735865a3 100644 --- a/environs/config/config.go +++ b/environs/config/config.go @@ -864,6 +864,14 @@ func Validate(cfg, old *Config) error { return errors.Trace(err) } + if err := cfg.validateNumProvisionWorkers(); err != nil { + return errors.Trace(err) + } + + if err := cfg.validateNumContainerProvisionWorkers(); err != nil { + return errors.Trace(err) + } + if old != nil { // Check the immutable config values. These can't change for _, attr := range immutableAttributes { @@ -1418,6 +1426,24 @@ func (c *Config) NumProvisionWorkers() int { return value } +const ( + MaxNumProvisionWorkers = 100 + MaxNumContainerProvisionWorkers = 25 +) + +// validateNumProvisionWorkers ensures the number cannot be set to +// more than 100. +// TODO: (hml) 26-Feb-2024 +// Once we can better link the controller config and the model config, +// allow the max value to be set in the controller config. +func (c *Config) validateNumProvisionWorkers() error { + value, ok := c.defined[NumProvisionWorkersKey].(int) + if ok && value > MaxNumProvisionWorkers { + return errors.Errorf("%s: must be less than %d", NumProvisionWorkersKey, MaxNumProvisionWorkers) + } + return nil +} + // NumContainerProvisionWorkers returns the number of container provisioner // workers to use. func (c *Config) NumContainerProvisionWorkers() int { @@ -1425,6 +1451,19 @@ func (c *Config) NumContainerProvisionWorkers() int { return value } +// validateNumContainerProvisionWorkers ensures the number cannot be set to +// more than 25. +// TODO: (hml) 26-Feb-2024 +// Once we can better link the controller config and the model config, +// allow the max value to be set in the controller config. +func (c *Config) validateNumContainerProvisionWorkers() error { + value, ok := c.defined[NumContainerProvisionWorkersKey].(int) + if ok && value > MaxNumContainerProvisionWorkers { + return errors.Errorf("%s: must be less than %d", NumContainerProvisionWorkersKey, MaxNumContainerProvisionWorkers) + } + return nil +} + // ImageStream returns the simplestreams stream // used to identify which image ids to search // when starting an instance. @@ -1438,7 +1477,7 @@ func (c *Config) ImageStream() string { // AgentStream returns the simplestreams stream // used to identify which tools to use when -// when bootstrapping or upgrading an environment. +// bootstrapping or upgrading an environment. func (c *Config) AgentStream() string { v, _ := c.defined[AgentStreamKey].(string) if v != "" { diff --git a/environs/config/config_test.go b/environs/config/config_test.go index 5ff3a7a825f..39abd3b12b6 100644 --- a/environs/config/config_test.go +++ b/environs/config/config_test.go @@ -364,15 +364,31 @@ var configTests = []configTest{ }), err: `provisioner-harvest-mode: expected one of \[all none unknown destroyed], got "yes please"`, }, { - about: fmt.Sprintf( - "%s: %d", - "num-provision-workers", - 42, - ), + about: fmt.Sprintf("num-provision-workers: 42"), + useDefaults: config.UseDefaults, + attrs: minimalConfigAttrs.Merge(testing.Attrs{ + "num-provision-workers": 42, + }), + }, { + about: fmt.Sprintf("num-provision-workers: over max"), + useDefaults: config.UseDefaults, + attrs: minimalConfigAttrs.Merge(testing.Attrs{ + "num-provision-workers": 101, + }), + err: `num-provision-workers: must be less than 100`, + }, { + about: fmt.Sprintf("num-container-provision-workers: 17"), + useDefaults: config.UseDefaults, + attrs: minimalConfigAttrs.Merge(testing.Attrs{ + "num-container-provision-workers": 17, + }), + }, { + about: fmt.Sprintf("num-container-provision-workers: over max"), useDefaults: config.UseDefaults, attrs: minimalConfigAttrs.Merge(testing.Attrs{ - "num-provision-workers": "42", + "num-container-provision-workers": 26, }), + err: `num-container-provision-workers: must be less than 25`, }, { about: "default image stream", useDefaults: config.UseDefaults, @@ -682,10 +698,14 @@ func (test configTest) check(c *gc.C) { cfg, err := config.New(test.useDefaults, test.attrs) if test.err != "" { c.Check(cfg, gc.IsNil) - c.Assert(err, gc.ErrorMatches, test.err) + c.Check(err, gc.ErrorMatches, test.err) + return + } + if !c.Check(err, jc.ErrorIsNil, gc.Commentf("config.New failed")) { + // As we have a Check not an Assert so the test should not + // continue from here as it will result in a nil pointer panic. return } - c.Assert(err, jc.ErrorIsNil) typ, _ := test.attrs["type"].(string) // "null" has been deprecated in favour of "manual", @@ -694,23 +714,23 @@ func (test configTest) check(c *gc.C) { typ = "manual" } name, _ := test.attrs["name"].(string) - c.Assert(cfg.Type(), gc.Equals, typ) - c.Assert(cfg.Name(), gc.Equals, name) + c.Check(cfg.Type(), gc.Equals, typ) + c.Check(cfg.Name(), gc.Equals, name) agentVersion, ok := cfg.AgentVersion() if s := test.attrs["agent-version"]; s != nil { - c.Assert(ok, jc.IsTrue) - c.Assert(agentVersion, gc.Equals, version.MustParse(s.(string))) + c.Check(ok, jc.IsTrue) + c.Check(agentVersion, gc.Equals, version.MustParse(s.(string))) } else { - c.Assert(ok, jc.IsFalse) - c.Assert(agentVersion, gc.Equals, version.Zero) + c.Check(ok, jc.IsFalse) + c.Check(agentVersion, gc.Equals, version.Zero) } if expected, ok := test.attrs["uuid"]; ok { - c.Assert(cfg.UUID(), gc.Equals, expected) + c.Check(cfg.UUID(), gc.Equals, expected) } dev, _ := test.attrs["development"].(bool) - c.Assert(cfg.Development(), gc.Equals, dev) + c.Check(cfg.Development(), gc.Equals, dev) baseAttr, _ := test.attrs["default-base"].(string) defaultBase, ok := cfg.DefaultBase() @@ -723,75 +743,76 @@ func (test configTest) check(c *gc.C) { } if m, _ := test.attrs["firewall-mode"].(string); m != "" { - c.Assert(cfg.FirewallMode(), gc.Equals, m) + c.Check(cfg.FirewallMode(), gc.Equals, m) } if m, _ := test.attrs["default-space"].(string); m != "" { - c.Assert(cfg.DefaultSpace(), gc.Equals, m) + c.Check(cfg.DefaultSpace(), gc.Equals, m) } keys, _ := test.attrs["authorized-keys"].(string) - c.Assert(cfg.AuthorizedKeys(), gc.Equals, keys) + c.Check(cfg.AuthorizedKeys(), gc.Equals, keys) lfCfg, hasLogCfg := cfg.LogFwdSyslog() if v, ok := test.attrs["logforward-enabled"].(bool); ok { - c.Assert(hasLogCfg, jc.IsTrue) - c.Assert(lfCfg.Enabled, gc.Equals, v) + if c.Check(hasLogCfg, jc.IsTrue) { + c.Check(lfCfg.Enabled, gc.Equals, v) + } } if v, ok := test.attrs["syslog-ca-cert"].(string); v != "" { - c.Assert(hasLogCfg, jc.IsTrue) - c.Assert(lfCfg.CACert, gc.Equals, v) + c.Check(hasLogCfg, jc.IsTrue) + c.Check(lfCfg.CACert, gc.Equals, v) } else if ok { - c.Assert(hasLogCfg, jc.IsTrue) + c.Check(hasLogCfg, jc.IsTrue) c.Check(lfCfg.CACert, gc.Equals, "") } if v, ok := test.attrs["syslog-client-cert"].(string); v != "" { - c.Assert(hasLogCfg, jc.IsTrue) - c.Assert(lfCfg.ClientCert, gc.Equals, v) + c.Check(hasLogCfg, jc.IsTrue) + c.Check(lfCfg.ClientCert, gc.Equals, v) } else if ok { - c.Assert(hasLogCfg, jc.IsTrue) + c.Check(hasLogCfg, jc.IsTrue) c.Check(lfCfg.ClientCert, gc.Equals, "") } if v, ok := test.attrs["syslog-client-key"].(string); v != "" { - c.Assert(hasLogCfg, jc.IsTrue) - c.Assert(lfCfg.ClientKey, gc.Equals, v) + c.Check(hasLogCfg, jc.IsTrue) + c.Check(lfCfg.ClientKey, gc.Equals, v) } else if ok { - c.Assert(hasLogCfg, jc.IsTrue) + c.Check(hasLogCfg, jc.IsTrue) c.Check(lfCfg.ClientKey, gc.Equals, "") } if v, ok := test.attrs["ssl-hostname-verification"]; ok { - c.Assert(cfg.SSLHostnameVerification(), gc.Equals, v) + c.Check(cfg.SSLHostnameVerification(), gc.Equals, v) } if v, ok := test.attrs["provisioner-harvest-mode"]; ok { harvestMeth, err := config.ParseHarvestMode(v.(string)) - c.Assert(err, jc.ErrorIsNil) - c.Assert(cfg.ProvisionerHarvestMode(), gc.Equals, harvestMeth) + c.Check(err, jc.ErrorIsNil) + c.Check(cfg.ProvisionerHarvestMode(), gc.Equals, harvestMeth) } else { - c.Assert(cfg.ProvisionerHarvestMode(), gc.Equals, config.HarvestDestroyed) + c.Check(cfg.ProvisionerHarvestMode(), gc.Equals, config.HarvestDestroyed) } if v, ok := test.attrs["image-stream"]; ok { - c.Assert(cfg.ImageStream(), gc.Equals, v) + c.Check(cfg.ImageStream(), gc.Equals, v) } else { - c.Assert(cfg.ImageStream(), gc.Equals, "released") + c.Check(cfg.ImageStream(), gc.Equals, "released") } url, urlPresent := cfg.ImageMetadataURL() if v, _ := test.attrs["image-metadata-url"].(string); v != "" { - c.Assert(url, gc.Equals, v) - c.Assert(urlPresent, jc.IsTrue) + c.Check(url, gc.Equals, v) + c.Check(urlPresent, jc.IsTrue) } else { - c.Assert(urlPresent, jc.IsFalse) + c.Check(urlPresent, jc.IsFalse) } agentURL, urlPresent := cfg.AgentMetadataURL() expectedToolsURLValue := test.attrs["agent-metadata-url"] if urlPresent { - c.Assert(agentURL, gc.Equals, expectedToolsURLValue) + c.Check(agentURL, gc.Equals, expectedToolsURLValue) } else { - c.Assert(agentURL, gc.Equals, "") + c.Check(agentURL, gc.Equals, "") } // assertions for deprecated tools-stream attribute used with new agent-stream @@ -812,33 +833,33 @@ func (test configTest) check(c *gc.C) { containerURL, urlPresent := cfg.ContainerImageMetadataURL() if v, _ := test.attrs["container-image-metadata-url"].(string); v != "" { - c.Assert(containerURL, gc.Equals, v) - c.Assert(urlPresent, jc.IsTrue) + c.Check(containerURL, gc.Equals, v) + c.Check(urlPresent, jc.IsTrue) } else { - c.Assert(urlPresent, jc.IsFalse) + c.Check(urlPresent, jc.IsFalse) } if v, ok := test.attrs["container-image-stream"]; ok { - c.Assert(cfg.ContainerImageStream(), gc.Equals, v) + c.Check(cfg.ContainerImageStream(), gc.Equals, v) } else { - c.Assert(cfg.ContainerImageStream(), gc.Equals, "released") + c.Check(cfg.ContainerImageStream(), gc.Equals, "released") } resourceTags, cfgHasResourceTags := cfg.ResourceTags() - c.Assert(cfgHasResourceTags, jc.IsTrue) + c.Check(cfgHasResourceTags, jc.IsTrue) if tags, ok := test.attrs["resource-tags"]; ok { switch tags := tags.(type) { case []string: if len(tags) > 0 { - c.Assert(resourceTags, jc.DeepEquals, testResourceTagsMap) + c.Check(resourceTags, jc.DeepEquals, testResourceTagsMap) } case string: if tags != "" { - c.Assert(resourceTags, jc.DeepEquals, testResourceTagsMap) + c.Check(resourceTags, jc.DeepEquals, testResourceTagsMap) } } } else { - c.Assert(resourceTags, gc.HasLen, 0) + c.Check(resourceTags, gc.HasLen, 0) } xmit := cfg.TransmitVendorMetrics() diff --git a/make_functions.sh b/make_functions.sh index 749bf765e92..e0545148305 100755 --- a/make_functions.sh +++ b/make_functions.sh @@ -135,14 +135,16 @@ build_push_operator_image() { ${output} \ "${BUILD_DIR}" elif [[ "${OCI_BUILDER}" = "podman" ]]; then + "$DOCKER_BIN" manifest rm "$(operator_image_path)" || true + "$DOCKER_BIN" manifest create "$(operator_image_path)" "$DOCKER_BIN" build \ --jobs "4" \ -f "${WORKDIR}/Dockerfile" \ - -t "$(operator_image_path)" \ + --manifest "$(operator_image_path)" \ --platform="$build_multi_osarch" \ "${BUILD_DIR}" if [[ "$push_image" = true ]]; then - "$DOCKER_BIN" push "$(operator_image_path)" + "$DOCKER_BIN" manifest push "$(operator_image_path)" "docker://$(operator_image_path)" fi else echo "unknown OCI_BUILDER=${OCI_BUILDER} expected docker or podman" diff --git a/state/modelconfig_test.go b/state/modelconfig_test.go index a31203c63e6..bd03f8f4364 100644 --- a/state/modelconfig_test.go +++ b/state/modelconfig_test.go @@ -458,7 +458,7 @@ func (s *ModelConfigSourceSuite) TestUpdateModelConfigDefaults(c *gc.C) { attrs = map[string]interface{}{ "apt-mirror": "http://different-mirror", - "num-provision-workers": 666, + "num-provision-workers": 66, } err = s.State.UpdateModelConfigDefaultValues(attrs, []string{"http-proxy", "https-proxy"}, nil) c.Assert(err, jc.ErrorIsNil) @@ -487,7 +487,7 @@ func (s *ModelConfigSourceSuite) TestUpdateModelConfigDefaults(c *gc.C) { Value: "dummy-proxy", }}} expectedValues["num-provision-workers"] = config.AttributeDefaultValues{ - Controller: 666, + Controller: 66, Default: 16, } c.Assert(cfg, jc.DeepEquals, expectedValues) diff --git a/worker/provisioner/provisioner_test.go b/worker/provisioner/provisioner_test.go index f77f6cfe4d3..0f918826d81 100644 --- a/worker/provisioner/provisioner_test.go +++ b/worker/provisioner/provisioner_test.go @@ -114,7 +114,7 @@ func (s *CommonProvisionerSuite) assertProvisionerObservesConfigChangesWorkerCou // Switch to reaping on All machines. attrs := map[string]interface{}{} if container { - attrs[config.NumContainerProvisionWorkersKey] = 42 + attrs[config.NumContainerProvisionWorkersKey] = 10 } else { attrs[config.NumProvisionWorkersKey] = 42 } @@ -130,7 +130,7 @@ func (s *CommonProvisionerSuite) assertProvisionerObservesConfigChangesWorkerCou select { case newCfg := <-cfgObserver: if container { - if newCfg.NumContainerProvisionWorkers() == 42 { + if newCfg.NumContainerProvisionWorkers() == 10 { return } received = append(received, newCfg.NumContainerProvisionWorkers())