diff --git a/Makefile b/Makefile index 4b59f2dc538..8d245256801 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,10 @@ BIN_DIR ?= ${BUILD_DIR}/${GOOS}_${GOARCH}/bin # for built juju binaries. JUJU_METADATA_SOURCE ?= ${BUILD_DIR}/simplestreams +# JUJU_PUBLISH_STREAM defines the simplestreams stream that we will publish +# agents to (default "released"). +JUJU_PUBLISH_STREAM ?= "released" + # TEST_PACKAGE_LIST is the path to a file that is a newline delimited list of # packages to test. This file must be sorted. TEST_PACKAGE_LIST ?= @@ -54,7 +58,7 @@ tool_platform_paths = $(addsuffix /${1},$(call bin_platform_paths,${2})) # simplestream_paths takes a list of Go style platforms to calculate the # paths to their respective simplestreams agent binary archives. -simplestream_paths = $(addprefix ${JUJU_METADATA_SOURCE}/, $(addprefix tools/released/juju-${JUJU_VERSION}-, $(addsuffix .tgz,$(subst /,-,${1})))) +simplestream_paths = $(addprefix ${JUJU_METADATA_SOURCE}/, $(addprefix tools/${JUJU_PUBLISH_STREAM}/juju-${JUJU_VERSION}-, $(addsuffix .tgz,$(subst /,-,${1})))) # CLIENT_PACKAGE_PLATFORMS defines a white space seperated list of platforms # to build the Juju client binaries for. Platforms are defined as GO style @@ -406,14 +410,14 @@ ${BUILD_DIR}/%/bin/pebble: phony_explicit # build for pebble $(run_go_build) -${JUJU_METADATA_SOURCE}/tools/released/juju-${JUJU_VERSION}-%.tgz: phony_explicit juju $(BUILD_AGENT_TARGETS) $(BUILD_CGO_AGENT_TARGETS) +${JUJU_METADATA_SOURCE}/tools/${JUJU_PUBLISH_STREAM}/juju-${JUJU_VERSION}-%.tgz: phony_explicit juju $(BUILD_AGENT_TARGETS) $(BUILD_CGO_AGENT_TARGETS) @echo "Packaging simplestream tools for juju ${JUJU_VERSION} on $*" - @mkdir -p ${JUJU_METADATA_SOURCE}/tools/released + @mkdir -p ${JUJU_METADATA_SOURCE}/tools/${JUJU_PUBLISH_STREAM} @tar czf "$@" -C $(call bin_platform_paths,$(subst -,/,$*)) . .PHONY: simplestreams simplestreams: juju juju-metadata ${SIMPLESTREAMS_TARGETS} - @juju metadata generate-agent-binaries -d ${JUJU_METADATA_SOURCE} --clean --prevent-fallback ; + @juju metadata generate-agent-binaries -d ${JUJU_METADATA_SOURCE} --clean --prevent-fallback --stream ${JUJU_PUBLISH_STREAM} ; @echo "\nRun export JUJU_METADATA_SOURCE=\"${JUJU_METADATA_SOURCE}\" if not defined in your env" .PHONY: build diff --git a/apiserver/facades/controller/agenttools/agenttools.go b/apiserver/facades/controller/agenttools/agenttools.go index 81dd80fd503..aa3f4ae469b 100644 --- a/apiserver/facades/controller/agenttools/agenttools.go +++ b/apiserver/facades/controller/agenttools/agenttools.go @@ -13,17 +13,12 @@ import ( "github.com/juju/juju/apiserver/facade" corelogger "github.com/juju/juju/core/logger" "github.com/juju/juju/environs" - "github.com/juju/juju/environs/config" "github.com/juju/juju/environs/simplestreams" "github.com/juju/juju/environs/tools" coretools "github.com/juju/juju/internal/tools" "github.com/juju/juju/state" ) -var ( - findTools = tools.FindTools -) - // AgentToolsAPI implements the API used by the machine model worker. type AgentToolsAPI struct { modelGetter ModelGetter @@ -33,6 +28,9 @@ type AgentToolsAPI struct { findTools toolsFinder envVersionUpdate envVersionUpdater logger corelogger.Logger + + modelConfigService ModelConfigService + modelAgentService ModelAgentService } // NewAgentToolsAPI creates a new instance of the Model API. @@ -43,14 +41,18 @@ func NewAgentToolsAPI( envVersionUpdate func(*state.Model, version.Number) error, authorizer facade.Authorizer, logger corelogger.Logger, + modelConfigService ModelConfigService, + modelAgentService ModelAgentService, ) (*AgentToolsAPI, error) { return &AgentToolsAPI{ - modelGetter: modelGetter, - newEnviron: newEnviron, - authorizer: authorizer, - findTools: findTools, - envVersionUpdate: envVersionUpdate, - logger: logger, + modelGetter: modelGetter, + newEnviron: newEnviron, + authorizer: authorizer, + findTools: findTools, + envVersionUpdate: envVersionUpdate, + logger: logger, + modelConfigService: modelConfigService, + modelAgentService: modelAgentService, }, nil } @@ -63,28 +65,25 @@ type newEnvironFunc func() (environs.Environ, error) type toolsFinder func(context.Context, tools.SimplestreamsFetcher, environs.BootstrapEnviron, int, int, []string, coretools.Filter) (coretools.List, error) type envVersionUpdater func(*state.Model, version.Number) error -func checkToolsAvailability(ctx context.Context, newEnviron newEnvironFunc, modelCfg *config.Config, finder toolsFinder) (version.Number, error) { - currentVersion, ok := modelCfg.AgentVersion() - if !ok || currentVersion == version.Zero { - return version.Zero, nil +func (api *AgentToolsAPI) checkToolsAvailability(ctx context.Context) (version.Number, error) { + currentVersion, err := api.modelAgentService.GetModelAgentVersion(ctx) + if err != nil { + return version.Zero, errors.Annotate(err, "getting agent version from service") } - env, err := newEnviron() + env, err := api.newEnviron() if err != nil { - return version.Zero, errors.Annotatef(err, "cannot make model") + return version.Zero, errors.Annotatef(err, "cannot make cloud provider") } ss := simplestreams.NewSimpleStreams(simplestreams.DefaultDataSourceFactory()) - - // finder receives major and minor as parameters as it uses them to filter versions and - // only return patches for the passed major.minor (from major.minor.patch). - // We'll try the released stream first, then fall back to the current configured stream - // if no released tools are found. - vers, err := finder(ctx, ss, env, currentVersion.Major, currentVersion.Minor, []string{tools.ReleasedStream}, coretools.Filter{}) - preferredStream := tools.PreferredStreams(¤tVersion, modelCfg.Development(), modelCfg.AgentStream())[0] - if preferredStream != tools.ReleasedStream && errors.Cause(err) == coretools.ErrNoMatches { - vers, err = finder(ctx, ss, env, currentVersion.Major, currentVersion.Minor, []string{preferredStream}, coretools.Filter{}) + modelCfg, err := api.modelConfigService.ModelConfig(ctx) + if err != nil { + return version.Zero, errors.Annotate(err, "cannot get model config") } + + preferredStreams := tools.PreferredStreams(¤tVersion, modelCfg.Development(), modelCfg.AgentStream()) + vers, err := api.findTools(ctx, ss, env, currentVersion.Major, currentVersion.Minor, preferredStreams, coretools.Filter{}) if err != nil { return version.Zero, errors.Annotatef(err, "cannot find available agent binaries") } @@ -94,25 +93,13 @@ func checkToolsAvailability(ctx context.Context, newEnviron newEnvironFunc, mode return newest, nil } -var modelConfig = func(e *state.Model) (*config.Config, error) { - return e.Config() -} - // Base implementation of envVersionUpdater func envVersionUpdate(env *state.Model, ver version.Number) error { return env.UpdateLatestToolsVersion(ver) } -func updateToolsAvailability(ctx context.Context, modelGetter ModelGetter, newEnviron newEnvironFunc, finder toolsFinder, update envVersionUpdater, logger corelogger.Logger) error { - model, err := modelGetter.Model() - if err != nil { - return errors.Annotate(err, "cannot get model") - } - cfg, err := modelConfig(model) - if err != nil { - return errors.Annotate(err, "cannot get config") - } - ver, err := checkToolsAvailability(ctx, newEnviron, cfg, finder) +func (api *AgentToolsAPI) updateToolsAvailability(ctx context.Context) error { + ver, err := api.checkToolsAvailability(ctx) if err != nil { if errors.Is(err, errors.NotFound) { // No newer tools, so exit silently. @@ -121,10 +108,15 @@ func updateToolsAvailability(ctx context.Context, modelGetter ModelGetter, newEn return errors.Annotate(err, "cannot get latest version") } if ver == version.Zero { - logger.Debugf("The lookup of agent binaries returned version Zero. This should only happen during bootstrap.") + api.logger.Debugf("The lookup of agent binaries returned version Zero. This should only happen during bootstrap.") return nil } - return update(model, ver) + + model, err := api.modelGetter.Model() + if err != nil { + return errors.Annotate(err, "cannot get model") + } + return api.envVersionUpdate(model, ver) } // UpdateToolsAvailable invokes a lookup and further update in environ @@ -133,5 +125,5 @@ func (api *AgentToolsAPI) UpdateToolsAvailable(ctx context.Context) error { if !api.authorizer.AuthController() { return apiservererrors.ErrPerm } - return updateToolsAvailability(ctx, api.modelGetter, api.newEnviron, api.findTools, api.envVersionUpdate, api.logger) + return api.updateToolsAvailability(ctx) } diff --git a/apiserver/facades/controller/agenttools/agenttools_test.go b/apiserver/facades/controller/agenttools/agenttools_test.go index 52cf044cb36..2a8c95d0435 100644 --- a/apiserver/facades/controller/agenttools/agenttools_test.go +++ b/apiserver/facades/controller/agenttools/agenttools_test.go @@ -9,6 +9,7 @@ import ( "github.com/juju/errors" jc "github.com/juju/testing/checkers" "github.com/juju/version/v2" + "go.uber.org/mock/gomock" gc "gopkg.in/check.v1" "github.com/juju/juju/environs" @@ -24,27 +25,31 @@ var _ = gc.Suite(&AgentToolsSuite{}) type AgentToolsSuite struct { coretesting.BaseSuite + modelConfigService *MockModelConfigService + modelAgentService *MockModelAgentService } type dummyEnviron struct { environs.Environ } -type configGetter struct { - cfg *config.Config -} - -func (s *configGetter) ModelConfig() (*config.Config, error) { - return s.cfg, nil +func (s *AgentToolsSuite) setupMocks(c *gc.C) *gomock.Controller { + ctrl := gomock.NewController(c) + s.modelConfigService = NewMockModelConfigService(ctrl) + s.modelAgentService = NewMockModelAgentService(ctrl) + return ctrl } func (s *AgentToolsSuite) TestCheckTools(c *gc.C) { - sConfig := coretesting.FakeConfig() - sConfig = sConfig.Merge(coretesting.Attrs{ - "agent-version": "2.5.0", - }) - cfg, err := config.New(config.NoDefaults, sConfig) + defer s.setupMocks(c).Finish() + + expVer, err := version.Parse("2.5.0") + c.Assert(err, jc.ErrorIsNil) + s.modelAgentService.EXPECT().GetModelAgentVersion(gomock.Any()).Return(expVer, nil) + modelConfig, err := config.New(config.NoDefaults, coretesting.FakeConfig()) c.Assert(err, jc.ErrorIsNil) + s.modelConfigService.EXPECT().ModelConfig(gomock.Any()).Return(modelConfig, nil) + var ( calledWithMajor, calledWithMinor int ) @@ -59,20 +64,29 @@ func (s *AgentToolsSuite) TestCheckTools(c *gc.C) { return coretools.List{&t}, nil } - ver, err := checkToolsAvailability(context.Background(), getDummyEnviron, cfg, fakeToolFinder) + api, err := NewAgentToolsAPI(nil, getDummyEnviron, fakeToolFinder, nil, nil, loggertesting.WrapCheckLog(c), s.modelConfigService, s.modelAgentService) + c.Assert(err, jc.ErrorIsNil) + + obtainedVer, err := api.checkToolsAvailability(context.Background()) c.Assert(err, jc.ErrorIsNil) - c.Assert(ver, gc.Not(gc.Equals), version.Zero) - c.Assert(ver, gc.Equals, version.Number{Major: 2, Minor: 5, Patch: 0}) + c.Assert(obtainedVer, gc.Equals, expVer) } func (s *AgentToolsSuite) TestCheckToolsNonReleasedStream(c *gc.C) { + defer s.setupMocks(c).Finish() + + expVer, err := version.Parse("2.5-alpha1") + c.Assert(err, jc.ErrorIsNil) + s.modelAgentService.EXPECT().GetModelAgentVersion(gomock.Any()).Return(expVer, nil) + sConfig := coretesting.FakeConfig() sConfig = sConfig.Merge(coretesting.Attrs{ - "agent-version": "2.5-alpha1", - "agent-stream": "proposed", + "agent-stream": "proposed", }) cfg, err := config.New(config.NoDefaults, sConfig) c.Assert(err, jc.ErrorIsNil) + s.modelConfigService.EXPECT().ModelConfig(gomock.Any()).Return(cfg, nil) + var ( calledWithMajor, calledWithMinor int calledWithStreams [][]string @@ -90,30 +104,31 @@ func (s *AgentToolsSuite) TestCheckToolsNonReleasedStream(c *gc.C) { c.Assert(calledWithMinor, gc.Equals, 5) return coretools.List{&t}, nil } - ver, err := checkToolsAvailability(context.Background(), getDummyEnviron, cfg, fakeToolFinder) + + api, err := NewAgentToolsAPI(nil, getDummyEnviron, fakeToolFinder, nil, nil, loggertesting.WrapCheckLog(c), s.modelConfigService, s.modelAgentService) c.Assert(err, jc.ErrorIsNil) - c.Assert(calledWithStreams, gc.DeepEquals, [][]string{{"released"}, {"proposed"}}) - c.Assert(ver, gc.Not(gc.Equals), version.Zero) - c.Assert(ver, gc.Equals, version.Number{Major: 2, Minor: 5, Patch: 0}) -} -type mockState struct { - configGetter + obtainedVer, err := api.checkToolsAvailability(context.Background()) + c.Assert(err, jc.ErrorIsNil) + c.Assert(calledWithStreams, gc.DeepEquals, [][]string{{"proposed", "released"}}) + c.Assert(obtainedVer, gc.Equals, version.Number{Major: 2, Minor: 5, Patch: 0}) } +type mockState struct{} + func (e *mockState) Model() (*state.Model, error) { return &state.Model{}, nil } func (s *AgentToolsSuite) TestUpdateToolsAvailability(c *gc.C) { - fakeModelConfig := func(_ *state.Model) (*config.Config, error) { - sConfig := coretesting.FakeConfig() - sConfig = sConfig.Merge(coretesting.Attrs{ - "agent-version": "2.5.0", - }) - return config.New(config.NoDefaults, sConfig) - } - s.PatchValue(&modelConfig, fakeModelConfig) + defer s.setupMocks(c).Finish() + + expVer, err := version.Parse("2.5.0") + c.Assert(err, jc.ErrorIsNil) + s.modelAgentService.EXPECT().GetModelAgentVersion(gomock.Any()).Return(expVer, nil) + modelConfig, err := config.New(config.NoDefaults, coretesting.FakeConfig()) + c.Assert(err, jc.ErrorIsNil) + s.modelConfigService.EXPECT().ModelConfig(gomock.Any()).Return(modelConfig, nil) fakeToolFinder := func(_ context.Context, _ tools.SimplestreamsFetcher, _ environs.BootstrapEnviron, _ int, _ int, _ []string, _ coretools.Filter) (coretools.List, error) { ver := version.Binary{Number: version.Number{Major: 2, Minor: 5, Patch: 2}} @@ -129,24 +144,23 @@ func (s *AgentToolsSuite) TestUpdateToolsAvailability(c *gc.C) { return nil } - cfg, err := config.New(config.NoDefaults, coretesting.FakeConfig()) - c.Assert(err, jc.ErrorIsNil) - err = updateToolsAvailability(context.Background(), &mockState{configGetter{cfg}}, getDummyEnviron, fakeToolFinder, fakeUpdate, loggertesting.WrapCheckLog(c)) + api, err := NewAgentToolsAPI(&mockState{}, getDummyEnviron, fakeToolFinder, fakeUpdate, nil, loggertesting.WrapCheckLog(c), s.modelConfigService, s.modelAgentService) c.Assert(err, jc.ErrorIsNil) - c.Assert(ver, gc.Not(gc.Equals), version.Zero) + err = api.updateToolsAvailability(context.Background()) + c.Assert(err, jc.ErrorIsNil) c.Assert(ver, gc.Equals, version.Number{Major: 2, Minor: 5, Patch: 2}) } func (s *AgentToolsSuite) TestUpdateToolsAvailabilityNoMatches(c *gc.C) { - fakeModelConfig := func(_ *state.Model) (*config.Config, error) { - sConfig := coretesting.FakeConfig() - sConfig = sConfig.Merge(coretesting.Attrs{ - "agent-version": "2.5.0", - }) - return config.New(config.NoDefaults, sConfig) - } - s.PatchValue(&modelConfig, fakeModelConfig) + defer s.setupMocks(c).Finish() + + expVer, err := version.Parse("2.5.0") + c.Assert(err, jc.ErrorIsNil) + s.modelAgentService.EXPECT().GetModelAgentVersion(gomock.Any()).Return(expVer, nil) + modelConfig, err := config.New(config.NoDefaults, coretesting.FakeConfig()) + c.Assert(err, jc.ErrorIsNil) + s.modelConfigService.EXPECT().ModelConfig(gomock.Any()).Return(modelConfig, nil) // No new tools available. fakeToolFinder := func(_ context.Context, _ tools.SimplestreamsFetcher, _ environs.BootstrapEnviron, _ int, _ int, _ []string, _ coretools.Filter) (coretools.List, error) { @@ -159,9 +173,10 @@ func (s *AgentToolsSuite) TestUpdateToolsAvailabilityNoMatches(c *gc.C) { return nil } - cfg, err := config.New(config.NoDefaults, coretesting.FakeConfig()) + api, err := NewAgentToolsAPI(&mockState{}, getDummyEnviron, fakeToolFinder, fakeUpdate, nil, loggertesting.WrapCheckLog(c), s.modelConfigService, s.modelAgentService) c.Assert(err, jc.ErrorIsNil) - err = updateToolsAvailability(context.Background(), &mockState{configGetter{cfg}}, getDummyEnviron, fakeToolFinder, fakeUpdate, loggertesting.WrapCheckLog(c)) + + err = api.updateToolsAvailability(context.Background()) c.Assert(err, jc.ErrorIsNil) } diff --git a/apiserver/facades/controller/agenttools/package_test.go b/apiserver/facades/controller/agenttools/package_test.go index 8a38cda4712..5af72a7ade9 100644 --- a/apiserver/facades/controller/agenttools/package_test.go +++ b/apiserver/facades/controller/agenttools/package_test.go @@ -9,6 +9,8 @@ import ( "github.com/juju/juju/testing" ) +//go:generate go run go.uber.org/mock/mockgen -typed -package agenttools -destination service_mock_test.go github.com/juju/juju/apiserver/facades/controller/agenttools ModelConfigService,ModelAgentService + func TestAll(t *stdtesting.T) { testing.MgoTestPackage(t) } diff --git a/apiserver/facades/controller/agenttools/register.go b/apiserver/facades/controller/agenttools/register.go index 82fb0751003..74c0f99ca17 100644 --- a/apiserver/facades/controller/agenttools/register.go +++ b/apiserver/facades/controller/agenttools/register.go @@ -11,6 +11,7 @@ import ( "github.com/juju/juju/apiserver/facade" "github.com/juju/juju/environs" + "github.com/juju/juju/environs/tools" "github.com/juju/juju/state/stateenvirons" ) @@ -32,5 +33,14 @@ func newFacade(ctx facade.ModelContext) (*AgentToolsAPI, error) { newEnviron := stateenvirons.GetNewEnvironFunc(environs.New) return newEnviron(model, ctx.ServiceFactory().Cloud(), ctx.ServiceFactory().Credential()) } - return NewAgentToolsAPI(st, newEnviron, findTools, envVersionUpdate, ctx.Auth(), ctx.Logger().Child("model")) + return NewAgentToolsAPI( + st, + newEnviron, + tools.FindTools, + envVersionUpdate, + ctx.Auth(), + ctx.Logger().Child("model"), + ctx.ServiceFactory().Config(), + ctx.ServiceFactory().Agent(), + ) } diff --git a/apiserver/facades/controller/agenttools/service.go b/apiserver/facades/controller/agenttools/service.go new file mode 100644 index 00000000000..3939b57c3e8 --- /dev/null +++ b/apiserver/facades/controller/agenttools/service.go @@ -0,0 +1,24 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package agenttools + +import ( + "context" + + "github.com/juju/version/v2" + + "github.com/juju/juju/environs/config" +) + +// ModelConfigService provides access to the model configuration. +type ModelConfigService interface { + // ModelConfig returns the current config for the model. + ModelConfig(context.Context) (*config.Config, error) +} + +// ModelAgentService provides access to the Juju agent version for the model. +type ModelAgentService interface { + // GetModelAgentVersion returns the agent version for the current model. + GetModelAgentVersion(ctx context.Context) (version.Number, error) +} diff --git a/apiserver/facades/controller/agenttools/service_mock_test.go b/apiserver/facades/controller/agenttools/service_mock_test.go new file mode 100644 index 00000000000..e5107027286 --- /dev/null +++ b/apiserver/facades/controller/agenttools/service_mock_test.go @@ -0,0 +1,143 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/juju/juju/apiserver/facades/controller/agenttools (interfaces: ModelConfigService,ModelAgentService) +// +// Generated by this command: +// +// mockgen -typed -package agenttools -destination service_mock_test.go github.com/juju/juju/apiserver/facades/controller/agenttools ModelConfigService,ModelAgentService +// + +// Package agenttools is a generated GoMock package. +package agenttools + +import ( + context "context" + reflect "reflect" + + config "github.com/juju/juju/environs/config" + version "github.com/juju/version/v2" + gomock "go.uber.org/mock/gomock" +) + +// MockModelConfigService is a mock of ModelConfigService interface. +type MockModelConfigService struct { + ctrl *gomock.Controller + recorder *MockModelConfigServiceMockRecorder +} + +// MockModelConfigServiceMockRecorder is the mock recorder for MockModelConfigService. +type MockModelConfigServiceMockRecorder struct { + mock *MockModelConfigService +} + +// NewMockModelConfigService creates a new mock instance. +func NewMockModelConfigService(ctrl *gomock.Controller) *MockModelConfigService { + mock := &MockModelConfigService{ctrl: ctrl} + mock.recorder = &MockModelConfigServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockModelConfigService) EXPECT() *MockModelConfigServiceMockRecorder { + return m.recorder +} + +// ModelConfig mocks base method. +func (m *MockModelConfigService) ModelConfig(arg0 context.Context) (*config.Config, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ModelConfig", arg0) + ret0, _ := ret[0].(*config.Config) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ModelConfig indicates an expected call of ModelConfig. +func (mr *MockModelConfigServiceMockRecorder) ModelConfig(arg0 any) *MockModelConfigServiceModelConfigCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModelConfig", reflect.TypeOf((*MockModelConfigService)(nil).ModelConfig), arg0) + return &MockModelConfigServiceModelConfigCall{Call: call} +} + +// MockModelConfigServiceModelConfigCall wrap *gomock.Call +type MockModelConfigServiceModelConfigCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockModelConfigServiceModelConfigCall) Return(arg0 *config.Config, arg1 error) *MockModelConfigServiceModelConfigCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockModelConfigServiceModelConfigCall) Do(f func(context.Context) (*config.Config, error)) *MockModelConfigServiceModelConfigCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockModelConfigServiceModelConfigCall) DoAndReturn(f func(context.Context) (*config.Config, error)) *MockModelConfigServiceModelConfigCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// MockModelAgentService is a mock of ModelAgentService interface. +type MockModelAgentService struct { + ctrl *gomock.Controller + recorder *MockModelAgentServiceMockRecorder +} + +// MockModelAgentServiceMockRecorder is the mock recorder for MockModelAgentService. +type MockModelAgentServiceMockRecorder struct { + mock *MockModelAgentService +} + +// NewMockModelAgentService creates a new mock instance. +func NewMockModelAgentService(ctrl *gomock.Controller) *MockModelAgentService { + mock := &MockModelAgentService{ctrl: ctrl} + mock.recorder = &MockModelAgentServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockModelAgentService) EXPECT() *MockModelAgentServiceMockRecorder { + return m.recorder +} + +// GetModelAgentVersion mocks base method. +func (m *MockModelAgentService) GetModelAgentVersion(arg0 context.Context) (version.Number, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetModelAgentVersion", arg0) + ret0, _ := ret[0].(version.Number) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetModelAgentVersion indicates an expected call of GetModelAgentVersion. +func (mr *MockModelAgentServiceMockRecorder) GetModelAgentVersion(arg0 any) *MockModelAgentServiceGetModelAgentVersionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetModelAgentVersion", reflect.TypeOf((*MockModelAgentService)(nil).GetModelAgentVersion), arg0) + return &MockModelAgentServiceGetModelAgentVersionCall{Call: call} +} + +// MockModelAgentServiceGetModelAgentVersionCall wrap *gomock.Call +type MockModelAgentServiceGetModelAgentVersionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockModelAgentServiceGetModelAgentVersionCall) Return(arg0 version.Number, arg1 error) *MockModelAgentServiceGetModelAgentVersionCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockModelAgentServiceGetModelAgentVersionCall) Do(f func(context.Context) (version.Number, error)) *MockModelAgentServiceGetModelAgentVersionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockModelAgentServiceGetModelAgentVersionCall) DoAndReturn(f func(context.Context) (version.Number, error)) *MockModelAgentServiceGetModelAgentVersionCall { + c.Call = c.Call.DoAndReturn(f) + return c +}