Skip to content

Commit

Permalink
Merge branch 'main' into users/lingyun/instanceHistory
Browse files Browse the repository at this point in the history
  • Loading branch information
linyguo authored Jan 24, 2025
2 parents f27240a + 55f5e2d commit 71c6a9c
Show file tree
Hide file tree
Showing 42 changed files with 496 additions and 183 deletions.
4 changes: 3 additions & 1 deletion api/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ var (
)

const (
FullGroupName = "symphony"
FullGroupName = "symphony"
TargetRuntimePrefix = "target-runtime"

// system annotations, reserved and should not be modified by client.
AzureCorrelationIdKey = "management.azure.com/correlationId"
Expand All @@ -28,6 +29,7 @@ const (
AzureResourceIdKey = "management.azure.com/resourceId"
AzureSystemDataKey = "management.azure.com/systemData"
AzureTenantIdKey = "management.azure.com/tenantId" // Not used
GuidKey = "Guid"
RunningAzureCorrelationIdKey = "management.azure.com/runningCorrelationId"
SummaryJobIdKey = "SummaryJobIdKey"
OperationStartTimeKeyPostfix = FullGroupName + "/started-at" // instance/target
Expand Down
3 changes: 2 additions & 1 deletion api/pkg/apis/v1alpha1/managers/jobs/jobs-manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"fmt"
"time"

"github.com/eclipse-symphony/symphony/api/constants"
"github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/model"
"github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils"
api_utils "github.com/eclipse-symphony/symphony/api/pkg/apis/v1alpha1/utils"
Expand Down Expand Up @@ -328,7 +329,7 @@ func (s *JobsManager) DelayOrSkipJob(ctx context.Context, namespace string, obje

key := "h_" + job.Id
if objectType == "target" {
key = fmt.Sprintf("h_%s-%s", "target-runtime", job.Id)
key = fmt.Sprintf("h_%s-%s", constants.TargetRuntimePrefix, job.Id)
}
//check if a manager is working on the job
var entry states.StateEntry
Expand Down
5 changes: 5 additions & 0 deletions api/pkg/apis/v1alpha1/managers/solution/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func New() (*Metrics, error) {

// Close closes all metrics.
func (m *Metrics) Close() {
if m == nil {
return
}

m.apiComponentCount.Close()
}

// ApiComponentCount gets the total count of components for an API operation.
Expand Down
56 changes: 37 additions & 19 deletions api/pkg/apis/v1alpha1/managers/solution/solution-manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (s *SolutionManager) getPreviousState(ctx context.Context, instance string,
log.InfofCtx(ctx, " M (Solution): failed to get previous state for instance %s in namespace %s: %+v", instance, namespace, err)
return nil
}
func (s *SolutionManager) GetSummary(ctx context.Context, key string, namespace string) (model.SummaryResult, error) {
func (s *SolutionManager) GetSummary(ctx context.Context, summaryId string, name string, namespace string) (model.SummaryResult, error) {
// lock.Lock()
// defer lock.Unlock()

Expand All @@ -182,28 +182,41 @@ func (s *SolutionManager) GetSummary(ctx context.Context, key string, namespace
defer observ_utils.CloseSpanWithError(span, &err)
defer observ_utils.EmitUserDiagnosticsLogs(ctx, &err)

log.InfofCtx(ctx, " M (Solution): get summary, key: %s, namespace: %s", key, namespace)
log.InfofCtx(ctx, " M (Solution): get summary, name: %s, summaryId: %s, namespace: %s", name, summaryId, namespace)

var state states.StateEntry
state, err = s.StateProvider.Get(ctx, states.GetRequest{
ID: fmt.Sprintf("%s-%s", "summary", key),
ID: fmt.Sprintf("%s-%s", "summary", summaryId),
Metadata: map[string]interface{}{
"namespace": namespace,
"group": model.SolutionGroup,
"version": "v1",
"resource": Summary,
},
})
if err != nil && api_utils.IsNotFound(err) {
// if get summary by guid not found, try to get the summary by name
log.InfofCtx(ctx, " M (Solution): failed to get deployment summary[%s] by summaryId, error: %+v. Try to get summary by name", summaryId, err)
state, err = s.StateProvider.Get(ctx, states.GetRequest{
ID: fmt.Sprintf("%s-%s", "summary", name),
Metadata: map[string]interface{}{
"namespace": namespace,
"group": model.SolutionGroup,
"version": "v1",
"resource": Summary,
},
})
}
if err != nil {
log.ErrorfCtx(ctx, " M (Solution): failed to get deployment summary[%s]: %+v", key, err)
log.ErrorfCtx(ctx, " M (Solution): failed to get deployment summary[%s]: %+v", summaryId, err)
return model.SummaryResult{}, err
}

var result model.SummaryResult
jData, _ := json.Marshal(state.Body)
err = json.Unmarshal(jData, &result)
if err != nil {
log.ErrorfCtx(ctx, " M (Solution): failed to deserailze deployment summary[%s]: %+v", key, err)
log.ErrorfCtx(ctx, " M (Solution): failed to deserailze deployment summary[%s]: %+v", summaryId, err)
return model.SummaryResult{}, err
}

Expand Down Expand Up @@ -324,8 +337,13 @@ func (s *SolutionManager) Reconcile(ctx context.Context, deployment model.Deploy
deploymentType = DeploymentType_Delete
}
summary.IsRemoval = remove
summaryId := deployment.Instance.ObjectMeta.GetSummaryId()
if summaryId == "" {
log.ErrorfCtx(ctx, " M (Solution): object GUID is null: %+v", err)
return summary, err
}

err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, deployment.Generation, deployment.Hash, summary, namespace)
err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, summaryId, deployment.Generation, deployment.Hash, summary, namespace)
if err != nil {
log.ErrorfCtx(ctx, " M (Solution): failed to save summary progress: %+v", err)
return summary, err
Expand All @@ -336,7 +354,7 @@ func (s *SolutionManager) Reconcile(ctx context.Context, deployment model.Deploy
if deployment.IsDryRun {
summary.SuccessCount = 0
}
s.concludeSummary(ctx, deployment.Instance.ObjectMeta.Name, deployment.Generation, deployment.Hash, summary, namespace)
s.concludeSummary(ctx, deployment.Instance.ObjectMeta.Name, summaryId, deployment.Generation, deployment.Hash, summary, namespace)
} else {
log.ErrorfCtx(ctx, " M (Solution): panic happens: %v", debug.Stack())
panic(r)
Expand Down Expand Up @@ -424,7 +442,7 @@ func (s *SolutionManager) Reconcile(ctx context.Context, deployment model.Deploy
summary.PlannedDeployment += len(step.Components)
}
summary.CurrentDeployed = 0
err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, deployment.Generation, deployment.Hash, summary, namespace)
err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, summaryId, deployment.Generation, deployment.Hash, summary, namespace)
if err != nil {
log.ErrorfCtx(ctx, " M (Solution): failed to save summary progress: %+v", err)
return summary, err
Expand Down Expand Up @@ -522,7 +540,7 @@ func (s *SolutionManager) Reconcile(ctx context.Context, deployment model.Deploy
targetResult[step.Target] = 1
summary.AllAssignedDeployed = plannedCount == planSuccessCount
summary.UpdateTargetResult(step.Target, model.TargetResultSpec{Status: "OK", Message: "", ComponentResults: componentResults})
err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, deployment.Generation, deployment.Hash, summary, namespace)
err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, summaryId, deployment.Generation, deployment.Hash, summary, namespace)
if err != nil {
log.ErrorfCtx(ctx, " M (Solution): failed to save summary progress: %+v", err)
return summary, err
Expand Down Expand Up @@ -559,7 +577,7 @@ func (s *SolutionManager) Reconcile(ctx context.Context, deployment model.Deploy
}
planSuccessCount++
summary.CurrentDeployed += len(step.Components)
err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, deployment.Generation, deployment.Hash, summary, namespace)
err = s.saveSummaryProgress(ctx, deployment.Instance.ObjectMeta.Name, summaryId, deployment.Generation, deployment.Hash, summary, namespace)
if err != nil {
log.ErrorfCtx(ctx, " M (Solution): failed to save summary progress: %+v", err)
return summary, err
Expand Down Expand Up @@ -636,11 +654,11 @@ func (s *SolutionManager) getTargetStateForStep(step model.DeploymentStep, deplo
return targetSpec
}

func (s *SolutionManager) saveSummary(ctx context.Context, objectName string, generation string, hash string, summary model.SummarySpec, state model.SummaryState, namespace string) error {
func (s *SolutionManager) saveSummary(ctx context.Context, objectName string, summaryId string, generation string, hash string, summary model.SummarySpec, state model.SummaryState, namespace string) error {
// TODO: delete this state when time expires. This should probably be invoked by the vendor (via GetSummary method, for instance)
log.DebugfCtx(ctx, " M (Solution): saving summary, objectName: %s, state: %s, namespace: %s, jobid: %s, hash %s, targetCount %d, successCount %d",
objectName, state, namespace, summary.JobID, hash, summary.TargetCount, summary.SuccessCount)
oldSummary, err := s.GetSummary(ctx, objectName, namespace)
log.DebugfCtx(ctx, " M (Solution): saving summary, objectName: %s, summaryId: %s, state: %v, namespace: %s, jobid: %s, hash %s, targetCount %d, successCount %d",
objectName, summaryId, state, namespace, summary.JobID, hash, summary.TargetCount, summary.SuccessCount)
oldSummary, err := s.GetSummary(ctx, summaryId, objectName, namespace)
if err != nil && !v1alpha2.IsNotFound(err) {
log.ErrorfCtx(ctx, " M (Solution): failed to get previous summary: %+v", err)
return err
Expand All @@ -664,7 +682,7 @@ func (s *SolutionManager) saveSummary(ctx context.Context, objectName string, ge
}
_, err = s.StateProvider.Upsert(ctx, states.UpsertRequest{
Value: states.StateEntry{
ID: fmt.Sprintf("%s-%s", "summary", objectName),
ID: fmt.Sprintf("%s-%s", "summary", summaryId),
Body: model.SummaryResult{
Summary: summary,
Generation: generation,
Expand All @@ -683,12 +701,12 @@ func (s *SolutionManager) saveSummary(ctx context.Context, objectName string, ge
return err
}

func (s *SolutionManager) saveSummaryProgress(ctx context.Context, objectName string, generation string, hash string, summary model.SummarySpec, namespace string) error {
return s.saveSummary(ctx, objectName, generation, hash, summary, model.SummaryStateRunning, namespace)
func (s *SolutionManager) saveSummaryProgress(ctx context.Context, objectName string, summaryId string, generation string, hash string, summary model.SummarySpec, namespace string) error {
return s.saveSummary(ctx, objectName, summaryId, generation, hash, summary, model.SummaryStateRunning, namespace)
}

func (s *SolutionManager) concludeSummary(ctx context.Context, objectName string, generation string, hash string, summary model.SummarySpec, namespace string) error {
return s.saveSummary(ctx, objectName, generation, hash, summary, model.SummaryStateDone, namespace)
func (s *SolutionManager) concludeSummary(ctx context.Context, objectName string, summaryId string, generation string, hash string, summary model.SummarySpec, namespace string) error {
return s.saveSummary(ctx, objectName, summaryId, generation, hash, summary, model.SummaryStateDone, namespace)
}

func (s *SolutionManager) canSkipStep(ctx context.Context, step model.DeploymentStep, target string, provider tgt.ITargetProvider, previousComponents []model.ComponentSpec, currentState model.DeploymentState) bool {
Expand Down
21 changes: 17 additions & 4 deletions api/pkg/apis/v1alpha1/managers/solution/solution-manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,12 @@ func TestSortByDepedenciesAllSelfReferences(t *testing.T) {
}
func TestMockGet(t *testing.T) {
id := uuid.New().String()
name := "testInstance"
deployment := model.DeploymentSpec{
Instance: model.InstanceState{
ObjectMeta: model.ObjectMeta{
Name: name,
},
Spec: &model.InstanceSpec{},
},
Solution: model.SolutionState{
Expand Down Expand Up @@ -354,6 +358,8 @@ func TestMockGet(t *testing.T) {
},
},
}
guid := uuid.New().String()
deployment.Instance.ObjectMeta.SetGuid(guid)
targetProvider := &mock.MockTargetProvider{}
targetProvider.Init(mock.MockTargetProviderConfig{})
stateProvider := &memorystate.MemoryStateProvider{}
Expand All @@ -372,7 +378,8 @@ func TestMockGet(t *testing.T) {
assert.Equal(t, 0, len(components))
assert.Equal(t, 0, len(state.TargetComponent))

_, err = manager.GetSummary(context.Background(), "", "default")
summaryKey := deployment.Instance.ObjectMeta.GetSummaryId()
_, err = manager.GetSummary(context.Background(), summaryKey, name, "default")
assert.NotNil(t, err)

_, err = manager.Reconcile(context.Background(), deployment, false, "default", "")
Expand All @@ -387,17 +394,17 @@ func TestMockGet(t *testing.T) {
assert.Equal(t, "mock", state.TargetComponent["a::T1"])
assert.Equal(t, "mock", state.TargetComponent["b::T1"])

_, err = manager.GetSummary(context.Background(), "", "default")
_, err = manager.GetSummary(context.Background(), summaryKey, name, "default")
assert.Nil(t, err)

// Test reconcile idempotency
_, err = manager.Reconcile(context.Background(), deployment, false, "default", "")
assert.Nil(t, err)

// Test summary deletion
err = manager.DeleteSummary(context.Background(), "", "default")
err = manager.DeleteSummary(context.Background(), summaryKey, "default")
assert.Nil(t, err)
_, err = manager.GetSummary(context.Background(), "", "default")
_, err = manager.GetSummary(context.Background(), summaryKey, name, "default")
assert.NotNil(t, err)
}
func TestMockGetTwoTargets(t *testing.T) {
Expand Down Expand Up @@ -464,6 +471,7 @@ func TestMockGetTwoTargets(t *testing.T) {
},
},
}
deployment.Instance.ObjectMeta.SetGuid(uuid.New().String())
targetProvider := &mock.MockTargetProvider{}
targetProvider.Init(mock.MockTargetProviderConfig{ID: id})
stateProvider := &memorystate.MemoryStateProvider{}
Expand Down Expand Up @@ -560,6 +568,7 @@ func TestMockGetTwoTargetsTwoProviders(t *testing.T) {
},
},
}
deployment.Instance.ObjectMeta.SetGuid(uuid.New().String())
targetProvider := &mock.MockTargetProvider{}
targetProvider.Init(mock.MockTargetProviderConfig{ID: id})
stateProvider := &memorystate.MemoryStateProvider{}
Expand Down Expand Up @@ -636,6 +645,7 @@ func TestMockApply(t *testing.T) {
},
},
}
deployment.Instance.ObjectMeta.SetGuid(uuid.New().String())
targetProvider := &mock.MockTargetProvider{}
targetProvider.Init(mock.MockTargetProviderConfig{ID: id})
stateProvider := &memorystate.MemoryStateProvider{}
Expand Down Expand Up @@ -698,6 +708,7 @@ func TestMockApplyMultiRoles(t *testing.T) {
},
},
}
deployment.Instance.ObjectMeta.SetGuid(uuid.New().String())
targetProvider := &mock.MockTargetProvider{}
targetProvider2 := &mock.MockTargetProvider{}
targetProvider.Init(mock.MockTargetProviderConfig{ID: id1})
Expand Down Expand Up @@ -759,6 +770,7 @@ func TestMockApplyWithUpdateAndRemove(t *testing.T) {
},
},
}
deployment.Instance.ObjectMeta.SetGuid(uuid.New().String())
targetProvider := &mock.MockTargetProvider{}
targetProvider.Init(mock.MockTargetProviderConfig{ID: id})
stateProvider := &memorystate.MemoryStateProvider{}
Expand Down Expand Up @@ -812,6 +824,7 @@ func TestMockApplyWithError(t *testing.T) {
},
},
}
deployment.Instance.ObjectMeta.SetGuid(uuid.New().String())
targetProvider := &mock.MockTargetProvider{}
targetProvider.Init(mock.MockTargetProviderConfig{ID: id})
stateProvider := &memorystate.MemoryStateProvider{}
Expand Down
25 changes: 25 additions & 0 deletions api/pkg/apis/v1alpha1/model/objectmeta.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ func (c ObjectMeta) DeepEquals(other IDeepEquals) (bool, error) {
return false, errors.New("parameter is not a ObjectMeta type")
}

if c.GetGuid() != otherC.GetGuid() {
return false, nil
}

if c.Name != otherC.Name {
return false, nil
}
Expand Down Expand Up @@ -150,3 +154,24 @@ func (c *ObjectMeta) PreserveSystemMetadata(metadata ObjectMeta) {
}
}
}

func (c *ObjectMeta) GetSummaryId() string {
if c.Annotations == nil || c.Annotations[constants.GuidKey] == "" {
return c.Name
}
return fmt.Sprintf("%s-%s", c.Name, c.Annotations[constants.GuidKey])
}

func (c *ObjectMeta) GetGuid() string {
if c.Annotations == nil {
return ""
}
return c.Annotations[constants.GuidKey]
}

func (c *ObjectMeta) SetGuid(guid string) {
if c.Annotations == nil {
c.Annotations = make(map[string]string)
}
c.Annotations[constants.GuidKey] = guid
}
1 change: 1 addition & 0 deletions api/pkg/apis/v1alpha1/providers/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func (m *Metrics) Close() {
return
}

m.providerOperationLatency.Close()
m.providerOperationErrors.Close()
}

Expand Down
Loading

0 comments on commit 71c6a9c

Please sign in to comment.