1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 15:59:41 +02:00

feat(edgestacks): add support for transactions EE-5326 (#8908)

This commit is contained in:
andres-portainer 2023-05-05 20:39:22 -03:00 committed by GitHub
parent 59f543f442
commit e82c88317e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 254 additions and 104 deletions

View file

@ -8,7 +8,7 @@ import (
"github.com/portainer/portainer/api/dataservices"
)
var ErrEdgeGroupNotFound = errors.New("Edge group was not found")
var ErrEdgeGroupNotFound = errors.New("edge group was not found")
// EdgeStackRelatedEndpoints returns a list of environments(endpoints) related to this Edge stack
func EdgeStackRelatedEndpoints(edgeGroupIDs []portainer.EdgeGroupID, endpoints []portainer.Endpoint, endpointGroups []portainer.EndpointGroup, edgeGroups []portainer.EdgeGroup) ([]portainer.EndpointID, error) {
@ -42,18 +42,18 @@ type EndpointRelationsConfig struct {
}
// FetchEndpointRelationsConfig fetches config needed for Edge Stack related endpoints
func FetchEndpointRelationsConfig(dataStore dataservices.DataStore) (*EndpointRelationsConfig, error) {
endpoints, err := dataStore.Endpoint().Endpoints()
func FetchEndpointRelationsConfig(tx dataservices.DataStoreTx) (*EndpointRelationsConfig, error) {
endpoints, err := tx.Endpoint().Endpoints()
if err != nil {
return nil, fmt.Errorf("unable to retrieve environments from database: %w", err)
}
endpointGroups, err := dataStore.EndpointGroup().EndpointGroups()
endpointGroups, err := tx.EndpointGroup().EndpointGroups()
if err != nil {
return nil, fmt.Errorf("unable to retrieve environment groups from database: %w", err)
}
edgeGroups, err := dataStore.EdgeGroup().EdgeGroups()
edgeGroups, err := tx.EdgeGroup().EdgeGroups()
if err != nil {
return nil, fmt.Errorf("unable to retrieve edge groups from database: %w", err)
}

View file

@ -6,12 +6,13 @@ import (
"strings"
"time"
"github.com/pkg/errors"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/internal/edge"
edgetypes "github.com/portainer/portainer/api/internal/edge/types"
"github.com/pkg/errors"
)
// Service represents a service for managing edge stacks.
@ -28,20 +29,20 @@ func NewService(dataStore dataservices.DataStore) *Service {
// BuildEdgeStack builds the initial edge stack object
// PersistEdgeStack is required to be called after this to persist the edge stack
func (service *Service) BuildEdgeStack(name string,
func (service *Service) BuildEdgeStack(
tx dataservices.DataStoreTx,
name string,
deploymentType portainer.EdgeStackDeploymentType,
edgeGroups []portainer.EdgeGroupID,
registries []portainer.RegistryID,
useManifestNamespaces bool,
) (*portainer.EdgeStack, error) {
edgeStacksService := service.dataStore.EdgeStack()
err := validateUniqueName(edgeStacksService.EdgeStacks, name)
err := validateUniqueName(tx.EdgeStack().EdgeStacks, name)
if err != nil {
return nil, err
}
stackID := edgeStacksService.GetNextIdentifier()
stackID := tx.EdgeStack().GetNextIdentifier()
return &portainer.EdgeStack{
ID: portainer.EdgeStackID(stackID),
Name: name,
@ -65,15 +66,17 @@ func validateUniqueName(edgeStacksGetter func() ([]portainer.EdgeStack, error),
return errors.New("Edge stack name must be unique")
}
}
return nil
}
// PersistEdgeStack persists the edge stack in the database and its relations
func (service *Service) PersistEdgeStack(
tx dataservices.DataStoreTx,
stack *portainer.EdgeStack,
storeManifest edgetypes.StoreManifestFunc) (*portainer.EdgeStack, error) {
relationConfig, err := edge.FetchEndpointRelationsConfig(service.dataStore)
relationConfig, err := edge.FetchEndpointRelationsConfig(tx)
if err != nil {
return nil, fmt.Errorf("unable to find environment relations in database: %w", err)
@ -98,12 +101,12 @@ func (service *Service) PersistEdgeStack(
stack.EntryPoint = composePath
stack.NumDeployments = len(relatedEndpointIds)
err = service.updateEndpointRelations(stack.ID, relatedEndpointIds)
err = service.updateEndpointRelations(tx, stack.ID, relatedEndpointIds)
if err != nil {
return nil, fmt.Errorf("unable to update endpoint relations: %w", err)
}
err = service.dataStore.EdgeStack().Create(stack.ID, stack)
err = tx.EdgeStack().Create(stack.ID, stack)
if err != nil {
return nil, err
}
@ -112,8 +115,8 @@ func (service *Service) PersistEdgeStack(
}
// updateEndpointRelations adds a relation between the Edge Stack to the related environments(endpoints)
func (service *Service) updateEndpointRelations(edgeStackID portainer.EdgeStackID, relatedEndpointIds []portainer.EndpointID) error {
endpointRelationService := service.dataStore.EndpointRelation()
func (service *Service) updateEndpointRelations(tx dataservices.DataStoreTx, edgeStackID portainer.EdgeStackID, relatedEndpointIds []portainer.EndpointID) error {
endpointRelationService := tx.EndpointRelation()
for _, endpointID := range relatedEndpointIds {
relation, err := endpointRelationService.EndpointRelation(endpointID)
@ -133,9 +136,8 @@ func (service *Service) updateEndpointRelations(edgeStackID portainer.EdgeStackI
}
// DeleteEdgeStack deletes the edge stack from the database and its relations
func (service *Service) DeleteEdgeStack(edgeStackID portainer.EdgeStackID, relatedEdgeGroupsIds []portainer.EdgeGroupID) error {
relationConfig, err := edge.FetchEndpointRelationsConfig(service.dataStore)
func (service *Service) DeleteEdgeStack(tx dataservices.DataStoreTx, edgeStackID portainer.EdgeStackID, relatedEdgeGroupsIds []portainer.EdgeGroupID) error {
relationConfig, err := edge.FetchEndpointRelationsConfig(tx)
if err != nil {
return errors.WithMessage(err, "Unable to retrieve environments relations config from database")
}
@ -146,20 +148,20 @@ func (service *Service) DeleteEdgeStack(edgeStackID portainer.EdgeStackID, relat
}
for _, endpointID := range relatedEndpointIds {
relation, err := service.dataStore.EndpointRelation().EndpointRelation(endpointID)
relation, err := tx.EndpointRelation().EndpointRelation(endpointID)
if err != nil {
return errors.WithMessage(err, "Unable to find environment relation in database")
}
delete(relation.EdgeStacks, edgeStackID)
err = service.dataStore.EndpointRelation().UpdateEndpointRelation(endpointID, relation)
err = tx.EndpointRelation().UpdateEndpointRelation(endpointID, relation)
if err != nil {
return errors.WithMessage(err, "Unable to persist environment relation in database")
}
}
err = service.dataStore.EdgeStack().DeleteEdgeStack(portainer.EdgeStackID(edgeStackID))
err = tx.EdgeStack().DeleteEdgeStack(portainer.EdgeStackID(edgeStackID))
if err != nil {
return errors.WithMessage(err, "Unable to remove the edge stack from the database")
}

View file

@ -25,7 +25,7 @@ func Test_updateEndpointRelation_successfulRuns(t *testing.T) {
service := NewService(dataStore)
err := service.updateEndpointRelations(edgeStackID, relatedIds)
err := service.updateEndpointRelations(dataStore, edgeStackID, relatedIds)
assert.NoError(t, err, "updateEndpointRelations should not fail")