From 6bd1a91fa4d3719dc56d3cf79ed36a8471a124f2 Mon Sep 17 00:00:00 2001 From: wallyworld Date: Fri, 13 Sep 2024 14:21:28 +1000 Subject: [PATCH 1/3] refactor(units): remove a piece of branching logic in state In application state, the logic for inserting and updating a unit was intertwined. They are now separate operations. --- domain/application/errors/errors.go | 4 + domain/application/service/application.go | 16 ++-- .../application/service/package_mock_test.go | 86 +++++++++++++----- domain/application/state/application.go | 89 +++++++++++-------- domain/application/state/application_test.go | 50 ++++++++++- 5 files changed, 175 insertions(+), 70 deletions(-) diff --git a/domain/application/errors/errors.go b/domain/application/errors/errors.go index 75f67fd4cf1..7d0fd897159 100644 --- a/domain/application/errors/errors.go +++ b/domain/application/errors/errors.go @@ -39,6 +39,10 @@ const ( // does not exist. UnitNotFound = errors.ConstError("unit not found") + // UnitAlreadyExists describes an error that occurs when the + // unit being created already exists. + UnitAlreadyExists = errors.ConstError("unit already exists") + // UnitNotAssigned describes an error that occurs when the unit being operated on // is not assigned. UnitNotAssigned = errors.ConstError("unit not assigned") diff --git a/domain/application/service/application.go b/domain/application/service/application.go index 78a69132ed3..edeecd57b32 100644 --- a/domain/application/service/application.go +++ b/domain/application/service/application.go @@ -49,10 +49,14 @@ type AtomicApplicationState interface { // application is not found. GetApplicationID(ctx domain.AtomicContext, name string) (coreapplication.ID, error) - // UpsertUnit creates or updates the specified application unit, returning - // an error satisfying [applicationerrors.ApplicationNotFoundError] if the - // application doesn't exist. - UpsertUnit(domain.AtomicContext, coreapplication.ID, application.UpsertUnitArg) error + // InsertUnit insert the specified application unit, returning an error + // satisfying [applicationerrors.UnitAlreadyExists] + // if the unit exists. + InsertUnit(domain.AtomicContext, coreapplication.ID, application.UpsertUnitArg) error + + // UpdateUnit updates the specified application unit, returning an error + // satisfying [applicationerrors.UnitNotFoundError] if the unit doesn't exist. + UpdateUnit(domain.AtomicContext, coreapplication.ID, application.UpsertUnitArg) error // GetApplicationLife looks up the life of the specified application, returning an error // satisfying [applicationerrors.ApplicationNotFoundError] if the application is not found. @@ -537,7 +541,7 @@ func (s *ApplicationService) RegisterCAASUnit(ctx context.Context, appName strin if unitLife == life.Dead { return fmt.Errorf("dead unit %q already exists%w", args.UnitName, errors.Hide(applicationerrors.UnitAlreadyExists)) } - return s.st.UpsertUnit(ctx, appID, unitArg) + return s.st.UpdateUnit(ctx, appID, unitArg) }) return errors.Annotatef(err, "saving caas unit %q", args.UnitName) } @@ -553,7 +557,7 @@ func (s *ApplicationService) insertCAASUnit( (appScale.Scaling && orderedID >= appScale.ScaleTarget) { return fmt.Errorf("unrequired unit %s is not assigned%w", *args.UnitName, errors.Hide(applicationerrors.UnitNotAssigned)) } - return s.st.UpsertUnit(ctx, appID, args) + return s.st.InsertUnit(ctx, appID, args) } // DeleteApplication deletes the specified application, returning an error diff --git a/domain/application/service/package_mock_test.go b/domain/application/service/package_mock_test.go index 471531cb9dd..54bbfddaaed 100644 --- a/domain/application/service/package_mock_test.go +++ b/domain/application/service/package_mock_test.go @@ -541,6 +541,44 @@ func (c *MockApplicationStateInitialWatchStatementUnitLifeCall) DoAndReturn(f fu return c } +// InsertUnit mocks base method. +func (m *MockApplicationState) InsertUnit(arg0 domain.AtomicContext, arg1 application.ID, arg2 application0.UpsertUnitArg) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InsertUnit", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// InsertUnit indicates an expected call of InsertUnit. +func (mr *MockApplicationStateMockRecorder) InsertUnit(arg0, arg1, arg2 any) *MockApplicationStateInsertUnitCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertUnit", reflect.TypeOf((*MockApplicationState)(nil).InsertUnit), arg0, arg1, arg2) + return &MockApplicationStateInsertUnitCall{Call: call} +} + +// MockApplicationStateInsertUnitCall wrap *gomock.Call +type MockApplicationStateInsertUnitCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockApplicationStateInsertUnitCall) Return(arg0 error) *MockApplicationStateInsertUnitCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockApplicationStateInsertUnitCall) Do(f func(domain.AtomicContext, application.ID, application0.UpsertUnitArg) error) *MockApplicationStateInsertUnitCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockApplicationStateInsertUnitCall) DoAndReturn(f func(domain.AtomicContext, application.ID, application0.UpsertUnitArg) error) *MockApplicationStateInsertUnitCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + // RunAtomic mocks base method. func (m *MockApplicationState) RunAtomic(arg0 context.Context, arg1 func(domain.AtomicContext) error) error { m.ctrl.T.Helper() @@ -770,78 +808,78 @@ func (c *MockApplicationStateStorageDefaultsCall) DoAndReturn(f func(context.Con return c } -// UpsertCloudService mocks base method. -func (m *MockApplicationState) UpsertCloudService(arg0 context.Context, arg1, arg2 string, arg3 network.SpaceAddresses) error { +// UpdateUnit mocks base method. +func (m *MockApplicationState) UpdateUnit(arg0 domain.AtomicContext, arg1 application.ID, arg2 application0.UpsertUnitArg) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpsertCloudService", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "UpdateUnit", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } -// UpsertCloudService indicates an expected call of UpsertCloudService. -func (mr *MockApplicationStateMockRecorder) UpsertCloudService(arg0, arg1, arg2, arg3 any) *MockApplicationStateUpsertCloudServiceCall { +// UpdateUnit indicates an expected call of UpdateUnit. +func (mr *MockApplicationStateMockRecorder) UpdateUnit(arg0, arg1, arg2 any) *MockApplicationStateUpdateUnitCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertCloudService", reflect.TypeOf((*MockApplicationState)(nil).UpsertCloudService), arg0, arg1, arg2, arg3) - return &MockApplicationStateUpsertCloudServiceCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUnit", reflect.TypeOf((*MockApplicationState)(nil).UpdateUnit), arg0, arg1, arg2) + return &MockApplicationStateUpdateUnitCall{Call: call} } -// MockApplicationStateUpsertCloudServiceCall wrap *gomock.Call -type MockApplicationStateUpsertCloudServiceCall struct { +// MockApplicationStateUpdateUnitCall wrap *gomock.Call +type MockApplicationStateUpdateUnitCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *MockApplicationStateUpsertCloudServiceCall) Return(arg0 error) *MockApplicationStateUpsertCloudServiceCall { +func (c *MockApplicationStateUpdateUnitCall) Return(arg0 error) *MockApplicationStateUpdateUnitCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *MockApplicationStateUpsertCloudServiceCall) Do(f func(context.Context, string, string, network.SpaceAddresses) error) *MockApplicationStateUpsertCloudServiceCall { +func (c *MockApplicationStateUpdateUnitCall) Do(f func(domain.AtomicContext, application.ID, application0.UpsertUnitArg) error) *MockApplicationStateUpdateUnitCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockApplicationStateUpsertCloudServiceCall) DoAndReturn(f func(context.Context, string, string, network.SpaceAddresses) error) *MockApplicationStateUpsertCloudServiceCall { +func (c *MockApplicationStateUpdateUnitCall) DoAndReturn(f func(domain.AtomicContext, application.ID, application0.UpsertUnitArg) error) *MockApplicationStateUpdateUnitCall { c.Call = c.Call.DoAndReturn(f) return c } -// UpsertUnit mocks base method. -func (m *MockApplicationState) UpsertUnit(arg0 domain.AtomicContext, arg1 application.ID, arg2 application0.UpsertUnitArg) error { +// UpsertCloudService mocks base method. +func (m *MockApplicationState) UpsertCloudService(arg0 context.Context, arg1, arg2 string, arg3 network.SpaceAddresses) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpsertUnit", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "UpsertCloudService", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } -// UpsertUnit indicates an expected call of UpsertUnit. -func (mr *MockApplicationStateMockRecorder) UpsertUnit(arg0, arg1, arg2 any) *MockApplicationStateUpsertUnitCall { +// UpsertCloudService indicates an expected call of UpsertCloudService. +func (mr *MockApplicationStateMockRecorder) UpsertCloudService(arg0, arg1, arg2, arg3 any) *MockApplicationStateUpsertCloudServiceCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertUnit", reflect.TypeOf((*MockApplicationState)(nil).UpsertUnit), arg0, arg1, arg2) - return &MockApplicationStateUpsertUnitCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertCloudService", reflect.TypeOf((*MockApplicationState)(nil).UpsertCloudService), arg0, arg1, arg2, arg3) + return &MockApplicationStateUpsertCloudServiceCall{Call: call} } -// MockApplicationStateUpsertUnitCall wrap *gomock.Call -type MockApplicationStateUpsertUnitCall struct { +// MockApplicationStateUpsertCloudServiceCall wrap *gomock.Call +type MockApplicationStateUpsertCloudServiceCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *MockApplicationStateUpsertUnitCall) Return(arg0 error) *MockApplicationStateUpsertUnitCall { +func (c *MockApplicationStateUpsertCloudServiceCall) Return(arg0 error) *MockApplicationStateUpsertCloudServiceCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *MockApplicationStateUpsertUnitCall) Do(f func(domain.AtomicContext, application.ID, application0.UpsertUnitArg) error) *MockApplicationStateUpsertUnitCall { +func (c *MockApplicationStateUpsertCloudServiceCall) Do(f func(context.Context, string, string, network.SpaceAddresses) error) *MockApplicationStateUpsertCloudServiceCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockApplicationStateUpsertUnitCall) DoAndReturn(f func(domain.AtomicContext, application.ID, application0.UpsertUnitArg) error) *MockApplicationStateUpsertUnitCall { +func (c *MockApplicationStateUpsertCloudServiceCall) DoAndReturn(f func(context.Context, string, string, network.SpaceAddresses) error) *MockApplicationStateUpsertCloudServiceCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/domain/application/state/application.go b/domain/application/state/application.go index a8263dd79aa..3551f4b1e57 100644 --- a/domain/application/state/application.go +++ b/domain/application/state/application.go @@ -392,6 +392,29 @@ func (st *ApplicationState) getUnit(ctx context.Context, tx *sqlair.TX, unitName return &unit, nil } +// InsertUnit insert the specified application unit, returning an error +// satisfying [applicationerrors.UnitAlreadyExists] +// if the unit exists. +func (st *ApplicationState) InsertUnit( + ctx domain.AtomicContext, appID coreapplication.ID, args application.UpsertUnitArg, +) error { + // Should not happen, defensive check. + if args.UnitName == nil { + return errors.New("unit name must be provided inserting a unit") + } + err := domain.Run(ctx, func(ctx context.Context, tx *sqlair.TX) error { + _, err := st.getUnit(ctx, tx, *args.UnitName) + if err == nil { + return fmt.Errorf("unit %q already exists%w", *args.UnitName, errors.Hide(applicationerrors.UnitAlreadyExists)) + } + if err != nil && !errors.Is(err, applicationerrors.UnitNotFound) { + return errors.Annotatef(err, "looking up unit %q", *args.UnitName) + } + return st.insertUnit(ctx, tx, appID, args) + }) + return errors.Annotatef(err, "inserting unit for application %q", appID) +} + func (st *ApplicationState) insertUnit( ctx context.Context, tx *sqlair.TX, appID coreapplication.ID, args application.UpsertUnitArg, ) error { @@ -448,35 +471,45 @@ func (st *ApplicationState) insertUnit( return nil } -func (st *ApplicationState) upsertUnit( - ctx context.Context, tx *sqlair.TX, toUpdate unitDetails, args application.UpsertUnitArg, +// UpdateUnit updates the specified application unit, returning an error +// satisfying [applicationerrors.UnitNotFoundError] if the unit doesn't exist. +func (st *ApplicationState) UpdateUnit( + ctx domain.AtomicContext, appID coreapplication.ID, args application.UpsertUnitArg, ) error { - if args.PasswordHash != nil { - toUpdate.PasswordHash = *args.PasswordHash - toUpdate.PasswordHashAlgorithmID = 0 //currently we only use sha256 - } + err := domain.Run(ctx, func(ctx context.Context, tx *sqlair.TX) error { + toUpdate, err := st.getUnit(ctx, tx, *args.UnitName) + if err != nil { + return errors.Trace(err) + } - updateUnit := ` + if args.PasswordHash != nil { + toUpdate.PasswordHash = *args.PasswordHash + toUpdate.PasswordHashAlgorithmID = 0 //currently we only use sha256 + } + + updateUnit := ` UPDATE unit SET life_id = $unitDetails.life_id, password_hash = $unitDetails.password_hash, password_hash_algorithm_id = $unitDetails.password_hash_algorithm_id WHERE uuid = $unitDetails.uuid ` - updateUnitStmt, err := st.Prepare(updateUnit, toUpdate) - if err != nil { - return errors.Trace(err) - } + updateUnitStmt, err := st.Prepare(updateUnit, *toUpdate) + if err != nil { + return errors.Trace(err) + } - if err := tx.Query(ctx, updateUnitStmt, toUpdate).Run(); err != nil { - return errors.Annotatef(err, "updating unit row for unit %q", toUpdate.Name) - } - if args.CloudContainer != nil { - if err := st.upsertUnitCloudContainer(ctx, tx, toUpdate.Name, toUpdate.NetNodeID, args.CloudContainer); err != nil { - return errors.Annotatef(err, "creating cloud container row for unit %q", toUpdate.Name) + if err := tx.Query(ctx, updateUnitStmt, toUpdate).Run(); err != nil { + return errors.Annotatef(err, "updating unit row for unit %q", toUpdate.Name) } - } - return nil + if args.CloudContainer != nil { + if err := st.upsertUnitCloudContainer(ctx, tx, toUpdate.Name, toUpdate.NetNodeID, args.CloudContainer); err != nil { + return errors.Annotatef(err, "updating cloud container row for unit %q", toUpdate.Name) + } + } + return nil + }) + return errors.Annotatef(err, "updating unit %q for application %q", *args.UnitName, appID) } func (st *ApplicationState) upsertUnitCloudContainer( @@ -783,24 +816,6 @@ func (st *ApplicationState) GetApplicationID(ctx domain.AtomicContext, name stri return appID, errors.Annotatef(err, "getting ID for %q", name) } -// UpsertUnit creates or updates the specified application unit, returning an error -// satisfying [applicationerrors.ApplicationNotFoundError] if the application doesn't exist. -func (st *ApplicationState) UpsertUnit( - ctx domain.AtomicContext, appID coreapplication.ID, args application.UpsertUnitArg, -) error { - err := domain.Run(ctx, func(ctx context.Context, tx *sqlair.TX) error { - unit, err := st.getUnit(ctx, tx, *args.UnitName) - if err != nil { - if errors.Is(err, applicationerrors.UnitNotFound) { - return st.insertUnit(ctx, tx, appID, args) - } - return errors.Trace(err) - } - return st.upsertUnit(ctx, tx, *unit, args) - }) - return errors.Annotatef(err, "upserting unit %q for application %q", *args.UnitName, appID) -} - // GetUnitLife looks up the life of the specified unit, returning an error // satisfying [applicationerrors.UnitNotFound] if the unit is not found. func (st *ApplicationState) GetUnitLife(ctx domain.AtomicContext, unitName string) (life.Life, error) { diff --git a/domain/application/state/application_test.go b/domain/application/state/application_test.go index 433d5ab1928..69ef55dc1f6 100644 --- a/domain/application/state/application_test.go +++ b/domain/application/state/application_test.go @@ -310,7 +310,7 @@ WHERE u.name=?`, c.Assert(providerId, gc.Equals, "some-id") } -func (s *applicationStateSuite) TestUpsertUnit(c *gc.C) { +func (s *applicationStateSuite) TestUpdateUnit(c *gc.C) { u := application.UpsertUnitArg{ UnitName: ptr("foo/666"), CloudContainer: &application.CloudContainer{ @@ -319,14 +319,21 @@ func (s *applicationStateSuite) TestUpsertUnit(c *gc.C) { } appID := s.createApplication(c, "foo", life.Alive, u) + err := s.state.RunAtomic(context.Background(), func(ctx domain.AtomicContext) error { + return s.state.UpdateUnit(ctx, appID, application.UpsertUnitArg{ + UnitName: ptr("foo/667"), + }) + }) + c.Assert(err, jc.ErrorIs, applicationerrors.UnitNotFound) + u = application.UpsertUnitArg{ UnitName: ptr("foo/666"), CloudContainer: &application.CloudContainer{ ProviderId: ptr("another-id"), }, } - err := s.state.RunAtomic(context.Background(), func(ctx domain.AtomicContext) error { - return s.state.UpsertUnit(ctx, appID, u) + err = s.state.RunAtomic(context.Background(), func(ctx domain.AtomicContext) error { + return s.state.UpdateUnit(ctx, appID, u) }) c.Assert(err, jc.ErrorIsNil) @@ -348,6 +355,43 @@ WHERE u.name=?`, c.Assert(providerId, gc.Equals, "another-id") } +func (s *applicationStateSuite) TestInsertUnit(c *gc.C) { + appID := s.createApplication(c, "foo", life.Alive) + + u := application.UpsertUnitArg{ + UnitName: ptr("foo/666"), + CloudContainer: &application.CloudContainer{ + ProviderId: ptr("some-id"), + }, + } + err := s.state.RunAtomic(context.Background(), func(ctx domain.AtomicContext) error { + return s.state.InsertUnit(ctx, appID, u) + }) + c.Assert(err, jc.ErrorIsNil) + + var ( + providerId string + ) + err = s.TxnRunner().StdTxn(context.Background(), func(ctx context.Context, tx *sql.Tx) error { + err = tx.QueryRowContext(ctx, ` +SELECT provider_id FROM cloud_container cc +JOIN unit u ON cc.net_node_uuid = u.net_node_uuid +WHERE u.name=?`, + "foo/666").Scan(&providerId) + if err != nil { + return err + } + return nil + }) + c.Assert(err, jc.ErrorIsNil) + c.Assert(providerId, gc.Equals, "some-id") + + err = s.state.RunAtomic(context.Background(), func(ctx domain.AtomicContext) error { + return s.state.InsertUnit(ctx, appID, u) + }) + c.Assert(err, jc.ErrorIs, applicationerrors.UnitAlreadyExists) +} + func (s *applicationStateSuite) TestGetUnitLife(c *gc.C) { u := application.UpsertUnitArg{ UnitName: ptr("foo/666"), From 662a62747074bbf01c73448c04d980da9212e799 Mon Sep 17 00:00:00 2001 From: wallyworld Date: Tue, 17 Sep 2024 13:06:22 +1000 Subject: [PATCH 2/3] chore: tidy up application/unit sql --- domain/application/state/application.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/domain/application/state/application.go b/domain/application/state/application.go index 3551f4b1e57..3e5e7d6d7f4 100644 --- a/domain/application/state/application.go +++ b/domain/application/state/application.go @@ -226,7 +226,7 @@ func (st *ApplicationState) checkApplicationExists(ctx context.Context, tx *sqla var appID applicationID appName := applicationName{Name: name} query := ` -SELECT application.uuid AS &applicationID.* +SELECT &applicationID.uuid FROM application WHERE name = $applicationName.name ` @@ -248,7 +248,7 @@ func (st *ApplicationState) lookupApplication(ctx context.Context, tx *sqlair.TX var appID applicationID appName := applicationName{Name: name} queryApplication := ` -SELECT (uuid) AS (&applicationID.*) +SELECT &applicationID.* FROM application WHERE name = $applicationName.name ` @@ -377,7 +377,7 @@ func (st *ApplicationState) AddUnits(ctx context.Context, applicationName string func (st *ApplicationState) getUnit(ctx context.Context, tx *sqlair.TX, unitName string) (*unitDetails, error) { unit := unitDetails{Name: unitName} - getUnit := `SELECT (*) AS (&unitDetails.*) FROM unit WHERE name = $unitDetails.name` + getUnit := `SELECT &unitDetails.* FROM unit WHERE name = $unitDetails.name` getUnitStmt, err := st.Prepare(getUnit, unit) if err != nil { return nil, errors.Trace(err) @@ -519,7 +519,7 @@ func (st *ApplicationState) upsertUnitCloudContainer( NetNodeID: netNodeID, } queryCloudContainer := ` -SELECT (*) AS (&cloudContainer.*) +SELECT &cloudContainer.* FROM cloud_container WHERE net_node_uuid = $cloudContainer.net_node_uuid ` @@ -629,7 +629,7 @@ func (st *ApplicationState) deleteUnit(ctx context.Context, tx *sqlair.TX, unitN unit := coreUnit{Name: unitName} - queryUnit := `SELECT uuid as &coreUnit.uuid FROM unit WHERE name = $coreUnit.name` + queryUnit := `SELECT &coreUnit.uuid FROM unit WHERE name = $coreUnit.name` queryUnitStmt, err := st.Prepare(queryUnit, unit) if err != nil { return errors.Trace(err) @@ -821,7 +821,7 @@ func (st *ApplicationState) GetApplicationID(ctx domain.AtomicContext, name stri func (st *ApplicationState) GetUnitLife(ctx domain.AtomicContext, unitName string) (life.Life, error) { unit := coreUnit{Name: unitName} queryUnit := ` -SELECT unit.life_id AS &coreUnit.* +SELECT &coreUnit.life_id FROM unit WHERE name = $coreUnit.name ` @@ -848,7 +848,7 @@ WHERE name = $coreUnit.name func (st *ApplicationState) SetUnitLife(ctx domain.AtomicContext, unitName string, l life.Life) error { unit := coreUnit{Name: unitName, LifeID: l} query := ` -SELECT uuid AS &coreUnit.uuid +SELECT &coreUnit.uuid FROM unit WHERE name = $coreUnit.name ` @@ -887,7 +887,7 @@ AND life_id < $coreUnit.life_id func (st *ApplicationState) GetApplicationScaleState(ctx domain.AtomicContext, appID coreapplication.ID) (application.ScaleState, error) { appScale := applicationScale{ApplicationID: appID.String()} queryScale := ` -SELECT (*) AS (&applicationScale.*) +SELECT &applicationScale.* FROM application_scale WHERE application_uuid = $applicationScale.application_uuid ` @@ -914,7 +914,7 @@ WHERE application_uuid = $applicationScale.application_uuid func (st *ApplicationState) GetApplicationLife(ctx domain.AtomicContext, appName string) (coreapplication.ID, life.Life, error) { app := applicationName{Name: appName} query := ` -SELECT (*) AS (&applicationID.*) +SELECT &applicationID.* FROM application a WHERE name = $applicationName.name ` From 79a50463ee521dfc67982f0a4dde940b78e40412 Mon Sep 17 00:00:00 2001 From: wallyworld Date: Tue, 17 Sep 2024 13:17:16 +1000 Subject: [PATCH 3/3] chore: remove space id from k8s unit args --- domain/application/errors/errors.go | 4 ---- domain/application/service/application.go | 6 +++--- domain/application/types.go | 1 - 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/domain/application/errors/errors.go b/domain/application/errors/errors.go index 7d0fd897159..87d10af2522 100644 --- a/domain/application/errors/errors.go +++ b/domain/application/errors/errors.go @@ -47,10 +47,6 @@ const ( // is not assigned. UnitNotAssigned = errors.ConstError("unit not assigned") - // UnitAlreadyExists describes an error that occurs when the - // unit being created already exists. - UnitAlreadyExists = errors.ConstError("unit already exists") - // UnitHasSubordinates describes an error that occurs when trying to set a unit's life // to Dead but it still has subordinates. UnitHasSubordinates = errors.ConstError("unit has subordinates") diff --git a/domain/application/service/application.go b/domain/application/service/application.go index edeecd57b32..de598ada5b6 100644 --- a/domain/application/service/application.go +++ b/domain/application/service/application.go @@ -302,11 +302,13 @@ func makeUpsertUnitArgs(in AddUnitArg) application.UpsertUnitArg { Ports: in.CloudContainer.Ports, } if in.CloudContainer.Address != nil { + // TODO(units) - handle the in.CloudContainer.Address space ID + // For k8s we'll initially create a /32 subnet off the container address + // and add that to the default space. result.CloudContainer.Address = &application.Address{ Value: in.CloudContainer.Address.Value, AddressType: string(in.CloudContainer.Address.AddressType()), Scope: string(in.CloudContainer.Address.Scope), - SpaceID: in.CloudContainer.Address.SpaceID, Origin: string(network.OriginProvider), } if in.CloudContainer.AddressOrigin != nil { @@ -520,8 +522,6 @@ func (s *ApplicationService) RegisterCAASUnit(ctx context.Context, appName strin } if args.Address != nil { addr := network.NewSpaceAddress(*args.Address, network.WithScope(network.ScopeMachineLocal)) - // k8s doesn't support spaces yet. - addr.SpaceID = network.AlphaSpaceId p.CloudContainer.Address = &addr origin := network.OriginProvider p.CloudContainer.AddressOrigin = &origin diff --git a/domain/application/types.go b/domain/application/types.go index 08b1ed00c4a..857894d8758 100644 --- a/domain/application/types.go +++ b/domain/application/types.go @@ -75,7 +75,6 @@ type Address struct { AddressType string Scope string Origin string - SpaceID string } // UpsertUnitArg contains parameters for adding a unit to state.