From 738eef4fccc84aadec4d9aaff92a1905500f1f50 Mon Sep 17 00:00:00 2001 From: Dejan Zele Pejchev Date: Mon, 30 Mar 2026 14:54:40 +0200 Subject: [PATCH 1/5] Add retry policy engine and matching primitives Introduces a policy-based retry engine that evaluates Error protos against configurable rules to decide whether a failed job run should be retried. This is dead code - nothing calls the engine yet. - types.go: Policy, Rule, Result, Action types with regex pre-compilation - extract.go: extract condition, exit code, termination message, and failure_category/failure_subcategory from armadaevents.Error. Exit code and termination message come from the first non-empty ContainerError in the PodError; categories come from the top-level Error fields. - matcher.go: AND-logic rule matching, first-match-wins rule list evaluation - engine.go: Evaluate() with global cap, policy retry limit, and rule matching - configuration: RetryPolicyConfig type, wired into SchedulingConfig - config.yaml: default retryPolicy (disabled, globalMaxRetries=20) Signed-off-by: Dejan Zele Pejchev --- config/scheduler/config.yaml | 3 + internal/common/errormatch/doc.go | 4 +- internal/common/errormatch/types.go | 5 +- .../scheduler/configuration/configuration.go | 2 + internal/scheduler/configuration/retry.go | 12 + internal/scheduler/retry/engine.go | 85 +++ internal/scheduler/retry/engine_test.go | 645 ++++++++++++++++++ internal/scheduler/retry/extract.go | 70 ++ internal/scheduler/retry/extract_test.go | 209 ++++++ internal/scheduler/retry/matcher.go | 61 ++ internal/scheduler/retry/types.go | 106 +++ 11 files changed, 1199 insertions(+), 3 deletions(-) create mode 100644 internal/scheduler/configuration/retry.go create mode 100644 internal/scheduler/retry/engine.go create mode 100644 internal/scheduler/retry/engine_test.go create mode 100644 internal/scheduler/retry/extract.go create mode 100644 internal/scheduler/retry/extract_test.go create mode 100644 internal/scheduler/retry/matcher.go create mode 100644 internal/scheduler/retry/types.go diff --git a/config/scheduler/config.yaml b/config/scheduler/config.yaml index 6bea9242c89..b29d432dc21 100644 --- a/config/scheduler/config.yaml +++ b/config/scheduler/config.yaml @@ -108,6 +108,9 @@ scheduling: maximumPerQueueSchedulingBurst: 1000 maxJobSchedulingContextsPerExecutor: 10000 maxRetries: 3 + retryPolicy: + enabled: false + globalMaxRetries: 5 dominantResourceFairnessResourcesToConsider: - "cpu" - "memory" diff --git a/internal/common/errormatch/doc.go b/internal/common/errormatch/doc.go index 8743532c815..862f429c0b1 100644 --- a/internal/common/errormatch/doc.go +++ b/internal/common/errormatch/doc.go @@ -8,6 +8,6 @@ // Condition constants ([ConditionOOMKilled], [ConditionEvicted], // [ConditionDeadlineExceeded]) and the [KnownConditions] map are provided // for config validation. Non-pod conditions ([ConditionPreempted], -// [ConditionLeaseReturned]) are also defined here for use by the retry -// engine but are not included in [KnownConditions]. +// [ConditionLeaseReturned], [ConditionAppError]) are also defined here +// for use by the retry engine but are not included in [KnownConditions]. package errormatch diff --git a/internal/common/errormatch/types.go b/internal/common/errormatch/types.go index ab903ea05a6..f9d68a7361c 100644 --- a/internal/common/errormatch/types.go +++ b/internal/common/errormatch/types.go @@ -30,10 +30,13 @@ const ( // Condition constants for non-pod error types (used by the retry engine). // These are not observable from Kubernetes pod status, so the executor -// categorizer cannot match them. +// categorizer cannot match them. ConditionAppError is the catch-all for +// a PodError whose KubernetesReason is AppError (i.e. container failed +// without a recognised pod-level reason). const ( ConditionPreempted = "Preempted" ConditionLeaseReturned = "LeaseReturned" + ConditionAppError = "AppError" ) // KnownConditions is the set of condition strings accepted by the executor diff --git a/internal/scheduler/configuration/configuration.go b/internal/scheduler/configuration/configuration.go index 13a0da11705..2e744ee538d 100644 --- a/internal/scheduler/configuration/configuration.go +++ b/internal/scheduler/configuration/configuration.go @@ -306,6 +306,8 @@ type SchedulingConfig struct { MaximumPerQueueSchedulingBurst int `validate:"gt=0"` // Maximum number of times a job is retried before considered failed. MaxRetries uint + // RetryPolicy controls the policy-based retry engine (disabled by default). + RetryPolicy RetryPolicyConfig // List of resource names, e.g., []string{"cpu", "memory"}, to consider when computing DominantResourceFairness costs. // Dominant resource fairness is the algorithm used to assign a cost to jobs and queues. DominantResourceFairnessResourcesToConsider []string diff --git a/internal/scheduler/configuration/retry.go b/internal/scheduler/configuration/retry.go new file mode 100644 index 00000000000..5f4b6b7efd9 --- /dev/null +++ b/internal/scheduler/configuration/retry.go @@ -0,0 +1,12 @@ +package configuration + +// RetryPolicyConfig controls the scheduler's retry policy behavior. +type RetryPolicyConfig struct { + // Enabled controls whether the retry policy engine is active. + Enabled bool `yaml:"enabled"` + // GlobalMaxRetries is the maximum number of retries per job across all + // policies. It is counted in retries (not failures): the initial failure + // does not consume budget, only subsequent re-leases do. A value of 0 + // disables the global cap; per-policy retryLimit still applies. + GlobalMaxRetries uint `yaml:"globalMaxRetries"` +} diff --git a/internal/scheduler/retry/engine.go b/internal/scheduler/retry/engine.go new file mode 100644 index 00000000000..af303fb0ae2 --- /dev/null +++ b/internal/scheduler/retry/engine.go @@ -0,0 +1,85 @@ +package retry + +import ( + "fmt" + + "github.com/armadaproject/armada/pkg/armadaevents" +) + +const ( + reasonMatchFail = "matched rule: Fail" + reasonMatchRetry = "matched rule: Retry" + reasonDefault = "no rule matched, using default action" +) + +// Engine evaluates retry policies against job run errors to decide whether +// a job should be retried or permanently failed. +type Engine struct { + globalMaxRetries uint +} + +// NewEngine creates a retry engine with the given hard upper limit on retries. +func NewEngine(globalMaxRetries uint) *Engine { + return &Engine{globalMaxRetries: globalMaxRetries} +} + +// Evaluate applies the policy rules to runError and returns a retry decision. +// +// failureCount and totalRuns include the run being evaluated, so the first +// call for a job has failureCount=1 and zero retries consumed. RetryLimit and +// globalMaxRetries both count retries (not failures): RetryLimit=3 allows 3 +// retries after the initial failure, i.e. 4 attempts total. A limit of 0 +// means unlimited (the global cap still applies to policy limits). +// +// policy must not be nil; runError may be nil (treated as "no decision"). +func (e *Engine) Evaluate(policy *Policy, runError *armadaevents.Error, failureCount uint32, totalRuns uint) Result { + if runError == nil { + return Result{ShouldRetry: false, Reason: "no error information available"} + } + + retriesUsed := uint(0) + if totalRuns > 0 { + retriesUsed = totalRuns - 1 + } + if e.globalMaxRetries > 0 && retriesUsed >= e.globalMaxRetries { + return Result{ + ShouldRetry: false, + Reason: fmt.Sprintf("global max retries exceeded (%d/%d)", retriesUsed, e.globalMaxRetries), + } + } + + matched := matchRules(policy.Rules, matchInput{ + condition: extractCondition(runError), + exitCode: extractExitCode(runError), + terminationMessage: extractTerminationMessage(runError), + isContainerFailure: runError.GetPodError() != nil, + category: extractCategory(runError), + subcategory: extractSubcategory(runError), + }) + + action, reason := policy.DefaultAction, reasonDefault + if matched != nil { + action = matched.Action + reason = reasonMatchRetry + if action == ActionFail { + reason = reasonMatchFail + } + } + + if action == ActionFail { + return Result{ShouldRetry: false, Reason: reason} + } + + policyRetriesUsed := uint32(0) + if failureCount > 0 { + policyRetriesUsed = failureCount - 1 + } + if policy.RetryLimit > 0 && policyRetriesUsed >= policy.RetryLimit { + return Result{ + ShouldRetry: false, + Reason: fmt.Sprintf("policy retry limit exceeded (%d/%d)", policyRetriesUsed, policy.RetryLimit), + } + } + + return Result{ShouldRetry: true, Reason: reason} +} diff --git a/internal/scheduler/retry/engine_test.go b/internal/scheduler/retry/engine_test.go new file mode 100644 index 00000000000..60f427e256a --- /dev/null +++ b/internal/scheduler/retry/engine_test.go @@ -0,0 +1,645 @@ +package retry + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/armadaproject/armada/internal/common/errormatch" + "github.com/armadaproject/armada/pkg/armadaevents" +) + +func makeOOMError() *armadaevents.Error { + return &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{ + KubernetesReason: armadaevents.KubernetesReason_OOM, + ContainerErrors: []*armadaevents.ContainerError{{ExitCode: 137, Message: "OOMKilled"}}, + }, + }, + FailureCategory: "infrastructure", + } +} + +func makeAppError(exitCode int32, message string) *armadaevents.Error { + return &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{ + KubernetesReason: armadaevents.KubernetesReason_AppError, + ContainerErrors: []*armadaevents.ContainerError{{ExitCode: exitCode, Message: message}}, + }, + }, + } +} + +func compilePolicy(t *testing.T, p *Policy) *Policy { + t.Helper() + require.NoError(t, CompileRules(p.Rules)) + return p +} + +func TestEngine_Evaluate(t *testing.T) { + tests := map[string]struct { + globalMax uint + policy *Policy + runError *armadaevents.Error + failureCount uint32 + totalRuns uint + expected Result + }{ + "condition match OOMKilled, action Fail": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnConditions: []string{errormatch.ConditionOOMKilled}}, + }, + }, + runError: makeOOMError(), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "condition match Evicted, action Retry": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{ + {Action: ActionRetry, OnConditions: []string{errormatch.ConditionEvicted}}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_Evicted}, + }, + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "matched rule: Retry"}, + }, + "condition match DeadlineExceeded": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnConditions: []string{errormatch.ConditionDeadlineExceeded}}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_DeadlineExceeded}, + }, + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "condition match Preempted": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{ + {Action: ActionRetry, OnConditions: []string{errormatch.ConditionPreempted}}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_JobRunPreemptedError{ + JobRunPreemptedError: &armadaevents.JobRunPreemptedError{}, + }, + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "matched rule: Retry"}, + }, + "condition match LeaseReturned": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{ + {Action: ActionRetry, OnConditions: []string{errormatch.ConditionLeaseReturned}}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodLeaseReturned{ + PodLeaseReturned: &armadaevents.PodLeaseReturned{}, + }, + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "matched rule: Retry"}, + }, + "condition match AppError": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnConditions: []string{errormatch.ConditionAppError}}, + }, + }, + runError: makeAppError(1, "crash"), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "exit code In match": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + { + Action: ActionFail, + OnExitCodes: &errormatch.ExitCodeMatcher{Operator: errormatch.ExitCodeOperatorIn, Values: []int32{42, 43}}, + }, + }, + }, + runError: makeAppError(42, ""), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "exit code NotIn match": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{ + { + Action: ActionRetry, + OnExitCodes: &errormatch.ExitCodeMatcher{Operator: errormatch.ExitCodeOperatorNotIn, Values: []int32{42}}, + }, + }, + }, + runError: makeAppError(1, ""), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "matched rule: Retry"}, + }, + "termination message regex match": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + { + Action: ActionFail, + OnTerminationMessage: &errormatch.RegexMatcher{Pattern: "(?i)cuda.*error"}, + }, + }, + }, + runError: makeAppError(1, "CUDA memory error on device 0"), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "termination message regex no match": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + { + Action: ActionFail, + OnTerminationMessage: &errormatch.RegexMatcher{Pattern: "(?i)cuda.*error"}, + }, + }, + }, + runError: makeAppError(1, "segfault"), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "no rule matched, using default action"}, + }, + "category match (any subcategory)": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnCategory: "gpu"}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_AppError}, + }, + FailureCategory: "gpu", + FailureSubcategory: "transient", + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "category match with subcategory match": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnCategory: "gpu", OnSubcategory: "transient"}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_AppError}, + }, + FailureCategory: "gpu", + FailureSubcategory: "transient", + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "category match but subcategory mismatch": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnCategory: "gpu", OnSubcategory: "permanent"}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_AppError}, + }, + FailureCategory: "gpu", + FailureSubcategory: "transient", + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "no rule matched, using default action"}, + }, + "category mismatch": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnCategory: "network"}, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_AppError}, + }, + FailureCategory: "gpu", + FailureSubcategory: "transient", + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "no rule matched, using default action"}, + }, + "first match wins": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{ + {Action: ActionRetry, OnConditions: []string{errormatch.ConditionAppError}}, + {Action: ActionFail, OnConditions: []string{errormatch.ConditionAppError}}, + }, + }, + runError: makeAppError(1, "crash"), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "matched rule: Retry"}, + }, + "no match returns DefaultAction Fail": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{ + {Action: ActionRetry, OnConditions: []string{errormatch.ConditionOOMKilled}}, + }, + }, + runError: makeAppError(1, ""), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "no rule matched, using default action"}, + }, + "no match returns DefaultAction Retry": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + {Action: ActionFail, OnConditions: []string{errormatch.ConditionOOMKilled}}, + }, + }, + runError: makeAppError(1, ""), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "no rule matched, using default action"}, + }, + "global cap exceeded": { + globalMax: 5, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + }, + runError: makeAppError(1, "crash"), + failureCount: 0, + // totalRuns=6 means 5 retries have already happened (initial run + // plus 5 re-leases). At globalMax=5 the cap is now reached. + totalRuns: 6, + expected: Result{ShouldRetry: false, Reason: "global max retries exceeded (5/5)"}, + }, + "retry limit exceeded": { + globalMax: 100, + policy: &Policy{ + Name: "test", + RetryLimit: 3, + DefaultAction: ActionRetry, + }, + runError: makeAppError(1, "crash"), + // failureCount=4 means 3 retries have already happened (initial + // failure plus 3 retry failures). At retryLimit=3 the cap is now + // reached. + failureCount: 4, + totalRuns: 4, + expected: Result{ShouldRetry: false, Reason: "policy retry limit exceeded (3/3)"}, + }, + "retry limit 0 means unlimited within global cap": { + globalMax: 100, + policy: &Policy{ + Name: "test", + RetryLimit: 0, + DefaultAction: ActionRetry, + }, + runError: makeAppError(1, "crash"), + failureCount: 50, + totalRuns: 50, + expected: Result{ShouldRetry: true, Reason: "no rule matched, using default action"}, + }, + "nil error returns fail": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + }, + runError: nil, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "no error information available"}, + }, + "exit code match reads from ContainerError": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + { + Action: ActionFail, + OnExitCodes: &errormatch.ExitCodeMatcher{Operator: errormatch.ExitCodeOperatorIn, Values: []int32{42}}, + }, + }, + }, + runError: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{ + KubernetesReason: armadaevents.KubernetesReason_AppError, + ContainerErrors: []*armadaevents.ContainerError{{ExitCode: 42, Message: "custom exit"}}, + }, + }, + }, + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "AND logic, all fields must match": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + { + Action: ActionFail, + OnConditions: []string{errormatch.ConditionAppError}, + OnExitCodes: &errormatch.ExitCodeMatcher{Operator: errormatch.ExitCodeOperatorIn, Values: []int32{42}}, + }, + }, + }, + // Condition matches but exit code does not + runError: makeAppError(1, ""), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: true, Reason: "no rule matched, using default action"}, + }, + "AND logic, both fields match": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + Rules: []Rule{ + { + Action: ActionFail, + OnConditions: []string{errormatch.ConditionAppError}, + OnExitCodes: &errormatch.ExitCodeMatcher{Operator: errormatch.ExitCodeOperatorIn, Values: []int32{42}}, + }, + }, + }, + runError: makeAppError(42, ""), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "matched rule: Fail"}, + }, + "empty rules returns DefaultAction": { + globalMax: 10, + policy: &Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{}, + }, + runError: makeAppError(1, "crash"), + failureCount: 0, + totalRuns: 1, + expected: Result{ShouldRetry: false, Reason: "no rule matched, using default action"}, + }, + "globalMaxRetries 0 means unlimited": { + globalMax: 0, + policy: &Policy{ + Name: "test", + DefaultAction: ActionRetry, + }, + runError: makeAppError(1, "crash"), + failureCount: 100, + totalRuns: 100, + expected: Result{ShouldRetry: true, Reason: "no rule matched, using default action"}, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + tc.policy = compilePolicy(t, tc.policy) + engine := NewEngine(tc.globalMax) + result := engine.Evaluate(tc.policy, tc.runError, tc.failureCount, tc.totalRuns) + assert.Equal(t, tc.expected, result) + }) + } +} + +func TestCompileRules_InvalidRegex(t *testing.T) { + rules := []Rule{ + { + Action: ActionFail, + OnTerminationMessage: &errormatch.RegexMatcher{Pattern: "[invalid"}, + }, + } + err := CompileRules(rules) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to compile termination message pattern") +} + +func TestValidatePolicy(t *testing.T) { + tests := map[string]struct { + policy Policy + expectError string + }{ + "valid policy with Fail default": { + policy: Policy{ + Name: "test", + DefaultAction: ActionFail, + Rules: []Rule{ + {Action: ActionRetry, OnConditions: []string{"OOMKilled"}}, + }, + }, + }, + "valid policy with Retry default": { + policy: Policy{ + Name: "test", + DefaultAction: ActionRetry, + }, + }, + "empty DefaultAction rejected": { + policy: Policy{Name: "test", DefaultAction: ""}, + expectError: "DefaultAction must be", + }, + "unknown DefaultAction rejected": { + policy: Policy{Name: "test", DefaultAction: "Skip"}, + expectError: "DefaultAction must be", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + err := ValidatePolicy(tc.policy) + if tc.expectError != "" { + require.Error(t, err) + assert.Contains(t, err.Error(), tc.expectError) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestCompileRules_Validation(t *testing.T) { + tests := map[string]struct { + rules []Rule + expectError string + }{ + "empty termination message pattern": { + rules: []Rule{ + { + Action: ActionFail, + OnTerminationMessage: &errormatch.RegexMatcher{Pattern: ""}, + }, + }, + expectError: "rule 0: OnTerminationMessage pattern must not be empty", + }, + "empty rule with no match fields": { + rules: []Rule{ + {Action: ActionFail}, + }, + expectError: "rule 0: must have at least one match field", + }, + "invalid exit code operator": { + rules: []Rule{ + { + Action: ActionFail, + OnExitCodes: &errormatch.ExitCodeMatcher{Operator: "BadOp", Values: []int32{1}}, + }, + }, + expectError: "rule 0: OnExitCodes operator must be", + }, + "empty exit code values": { + rules: []Rule{ + { + Action: ActionFail, + OnExitCodes: &errormatch.ExitCodeMatcher{Operator: errormatch.ExitCodeOperatorIn, Values: []int32{}}, + }, + }, + expectError: "rule 0: OnExitCodes values must not be empty", + }, + "empty Action rejected": { + rules: []Rule{ + {OnConditions: []string{errormatch.ConditionOOMKilled}}, + }, + expectError: `rule 0: Action must be "Fail" or "Retry", got ""`, + }, + "unknown Action rejected": { + rules: []Rule{ + {Action: "Skip", OnConditions: []string{errormatch.ConditionOOMKilled}}, + }, + expectError: `rule 0: Action must be "Fail" or "Retry", got "Skip"`, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + err := CompileRules(tc.rules) + require.Error(t, err) + assert.Contains(t, err.Error(), tc.expectError) + }) + } +} + +// TestMatchRule_UncompiledPatternFailsClosed ensures that a Rule with a regex +// matcher set but the corresponding compiled pattern nil (CompileRules was not +// called) does not vacuously match every error. +func TestMatchRule_UncompiledPatternFailsClosed(t *testing.T) { + rule := &Rule{ + Action: ActionFail, + OnTerminationMessage: &errormatch.RegexMatcher{Pattern: ".*"}, + } + assert.False(t, matchRule(rule, matchInput{isContainerFailure: true, terminationMessage: "anything"}), + "uncompiled OnTerminationMessage must not vacuously match") +} + +// TestEvaluate_OnTerminationMessageIgnoredForNonContainerFailures pins the +// isContainerFailure guard in matchRule: a wildcard OnTerminationMessage +// pattern must not fire for lease returns or preemptions. See the matchInput +// doc comment for why. +func TestEvaluate_OnTerminationMessageIgnoredForNonContainerFailures(t *testing.T) { + tests := map[string]*armadaevents.Error{ + "PodLeaseReturned": {Reason: &armadaevents.Error_PodLeaseReturned{PodLeaseReturned: &armadaevents.PodLeaseReturned{}}}, + "JobRunPreemptedError": {Reason: &armadaevents.Error_JobRunPreemptedError{JobRunPreemptedError: &armadaevents.JobRunPreemptedError{}}}, + } + + for name, runErr := range tests { + t.Run(name, func(t *testing.T) { + engine := NewEngine(0) + policy := &Policy{ + Name: "p", + DefaultAction: ActionFail, + Rules: []Rule{ + {Action: ActionRetry, OnTerminationMessage: &errormatch.RegexMatcher{Pattern: ".*"}}, + }, + } + require.NoError(t, CompileRules(policy.Rules)) + + result := engine.Evaluate(policy, runErr, 0, 1) + assert.False(t, result.ShouldRetry, + "wildcard OnTerminationMessage must not match non-container failures; otherwise lease-return/preemption silently triggers retries") + assert.Equal(t, "no rule matched, using default action", result.Reason) + }) + } +} diff --git a/internal/scheduler/retry/extract.go b/internal/scheduler/retry/extract.go new file mode 100644 index 00000000000..5da551de843 --- /dev/null +++ b/internal/scheduler/retry/extract.go @@ -0,0 +1,70 @@ +package retry + +import ( + "github.com/armadaproject/armada/internal/common/errormatch" + "github.com/armadaproject/armada/pkg/armadaevents" +) + +// extractCondition derives a condition string from the Error oneof, or "" for +// unrecognised error types. +func extractCondition(err *armadaevents.Error) string { + if err == nil { + return "" + } + switch reason := err.Reason.(type) { + case *armadaevents.Error_PodError: + if reason.PodError == nil { + return "" + } + switch reason.PodError.KubernetesReason { + case armadaevents.KubernetesReason_OOM: + return errormatch.ConditionOOMKilled + case armadaevents.KubernetesReason_Evicted: + return errormatch.ConditionEvicted + case armadaevents.KubernetesReason_DeadlineExceeded: + return errormatch.ConditionDeadlineExceeded + case armadaevents.KubernetesReason_AppError: + return errormatch.ConditionAppError + default: + return "" + } + case *armadaevents.Error_JobRunPreemptedError: + return errormatch.ConditionPreempted + case *armadaevents.Error_PodLeaseReturned: + return errormatch.ConditionLeaseReturned + default: + return "" + } +} + +// extractExitCode returns the exit code from the first ContainerError in a PodError. +func extractExitCode(err *armadaevents.Error) int32 { + if pe := err.GetPodError(); pe != nil { + for _, ce := range pe.ContainerErrors { + if ce != nil && ce.ExitCode != 0 { + return ce.ExitCode + } + } + } + return 0 +} + +// extractTerminationMessage returns the termination message from the first ContainerError in a PodError. +func extractTerminationMessage(err *armadaevents.Error) string { + if pe := err.GetPodError(); pe != nil { + for _, ce := range pe.ContainerErrors { + if ce != nil && ce.Message != "" { + return ce.Message + } + } + } + return "" +} + +func extractCategory(err *armadaevents.Error) string { + return err.GetFailureCategory() +} + +func extractSubcategory(err *armadaevents.Error) string { + return err.GetFailureSubcategory() +} diff --git a/internal/scheduler/retry/extract_test.go b/internal/scheduler/retry/extract_test.go new file mode 100644 index 00000000000..a5b7b73091f --- /dev/null +++ b/internal/scheduler/retry/extract_test.go @@ -0,0 +1,209 @@ +package retry + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/armadaproject/armada/internal/common/errormatch" + "github.com/armadaproject/armada/pkg/armadaevents" +) + +func TestExtractCondition(t *testing.T) { + tests := map[string]struct { + err *armadaevents.Error + expected string + }{ + "nil error": { + err: nil, + expected: "", + }, + "PodError OOM": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_OOM}, + }, + }, + expected: errormatch.ConditionOOMKilled, + }, + "PodError Evicted": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_Evicted}, + }, + }, + expected: errormatch.ConditionEvicted, + }, + "PodError DeadlineExceeded": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_DeadlineExceeded}, + }, + }, + expected: errormatch.ConditionDeadlineExceeded, + }, + "PodError AppError": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{KubernetesReason: armadaevents.KubernetesReason_AppError}, + }, + }, + expected: errormatch.ConditionAppError, + }, + "PodError nil inner": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{PodError: nil}, + }, + expected: "", + }, + "Preempted": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_JobRunPreemptedError{ + JobRunPreemptedError: &armadaevents.JobRunPreemptedError{}, + }, + }, + expected: errormatch.ConditionPreempted, + }, + "LeaseReturned": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodLeaseReturned{ + PodLeaseReturned: &armadaevents.PodLeaseReturned{}, + }, + }, + expected: errormatch.ConditionLeaseReturned, + }, + "unrecognized error type": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_LeaseExpired{ + LeaseExpired: &armadaevents.LeaseExpired{}, + }, + }, + expected: "", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.expected, extractCondition(tc.err)) + }) + } +} + +func TestExtractExitCode(t *testing.T) { + tests := map[string]struct { + err *armadaevents.Error + expected int32 + }{ + "nil error": { + err: nil, + expected: 0, + }, + "from ContainerError": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{ + ContainerErrors: []*armadaevents.ContainerError{{ExitCode: 42}}, + }, + }, + }, + expected: 42, + }, + "first non-zero ContainerError wins": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{ + ContainerErrors: []*armadaevents.ContainerError{ + {ExitCode: 0}, + {ExitCode: 99}, + }, + }, + }, + }, + expected: 99, + }, + "no exit code anywhere": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{}, + }, + }, + expected: 0, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.expected, extractExitCode(tc.err)) + }) + } +} + +func TestExtractTerminationMessage(t *testing.T) { + tests := map[string]struct { + err *armadaevents.Error + expected string + }{ + "nil error": { + err: nil, + expected: "", + }, + "from ContainerError": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{ + ContainerErrors: []*armadaevents.ContainerError{{Message: "segfault"}}, + }, + }, + }, + expected: "segfault", + }, + "no message anywhere": { + err: &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{}, + }, + }, + expected: "", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.expected, extractTerminationMessage(tc.err)) + }) + } +} + +func TestExtractCategory(t *testing.T) { + tests := map[string]struct { + err *armadaevents.Error + expected string + }{ + "nil error": {err: nil, expected: ""}, + "category set": {err: &armadaevents.Error{FailureCategory: "infrastructure"}, expected: "infrastructure"}, + "only subcategory set": {err: &armadaevents.Error{FailureSubcategory: "oom"}, expected: ""}, + "both empty": {err: &armadaevents.Error{}, expected: ""}, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.expected, extractCategory(tc.err)) + }) + } +} + +func TestExtractSubcategory(t *testing.T) { + tests := map[string]struct { + err *armadaevents.Error + expected string + }{ + "nil error": {err: nil, expected: ""}, + "subcategory set": {err: &armadaevents.Error{FailureSubcategory: "oom"}, expected: "oom"}, + "only category set": {err: &armadaevents.Error{FailureCategory: "infrastructure"}, expected: ""}, + "both empty": {err: &armadaevents.Error{}, expected: ""}, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.expected, extractSubcategory(tc.err)) + }) + } +} diff --git a/internal/scheduler/retry/matcher.go b/internal/scheduler/retry/matcher.go new file mode 100644 index 00000000000..873e64a4f50 --- /dev/null +++ b/internal/scheduler/retry/matcher.go @@ -0,0 +1,61 @@ +package retry + +import ( + "slices" + + "github.com/armadaproject/armada/internal/common/errormatch" +) + +// matchInput bundles every signal a rule may match against. +// +// isContainerFailure gates OnTerminationMessage matching: lease returns and +// preemptions have no termination message, so a permissive pattern like ".*" +// would otherwise match their empty default and silently fire. +type matchInput struct { + condition string + exitCode int32 + terminationMessage string + isContainerFailure bool + category string + subcategory string +} + +// matchRule returns true if all non-empty match fields on the rule match the +// given input. Empty/nil match fields are ignored (they match anything). +func matchRule(rule *Rule, in matchInput) bool { + if len(rule.OnConditions) > 0 && !slices.Contains(rule.OnConditions, in.condition) { + return false + } + if rule.OnExitCodes != nil && !errormatch.MatchExitCode(rule.OnExitCodes, in.exitCode) { + return false + } + if rule.OnTerminationMessage != nil { + // Fail closed if CompileRules was not called: an uncompiled pattern + // must never vacuously match every error. + if !in.isContainerFailure || rule.compiledTerminationMessage == nil { + return false + } + if !errormatch.MatchPattern(rule.compiledTerminationMessage, in.terminationMessage) { + return false + } + } + if rule.OnCategory != "" { + if in.category != rule.OnCategory { + return false + } + if rule.OnSubcategory != "" && in.subcategory != rule.OnSubcategory { + return false + } + } + return true +} + +// matchRules returns the first rule that matches in, or nil if none do. +func matchRules(rules []Rule, in matchInput) *Rule { + for i := range rules { + if matchRule(&rules[i], in) { + return &rules[i] + } + } + return nil +} diff --git a/internal/scheduler/retry/types.go b/internal/scheduler/retry/types.go new file mode 100644 index 00000000000..9c7f3417518 --- /dev/null +++ b/internal/scheduler/retry/types.go @@ -0,0 +1,106 @@ +package retry + +import ( + "fmt" + "regexp" + + "github.com/armadaproject/armada/internal/common/errormatch" +) + +// Action is the decision made by the retry engine. +type Action string + +const ( + ActionFail Action = "Fail" + ActionRetry Action = "Retry" +) + +// Policy is the internal representation used by the engine. +// Converted from the api.RetryPolicy proto at cache refresh time (in a later PR). +type Policy struct { + Name string + RetryLimit uint32 + DefaultAction Action + Rules []Rule +} + +// Rule defines a single matching rule within a policy. +// All non-empty match fields must match for the rule to apply (AND logic across fields). +// OnSubcategory is only valid when OnCategory is set; it narrows a category match. +type Rule struct { + Action Action + OnConditions []string + OnExitCodes *errormatch.ExitCodeMatcher + OnTerminationMessage *errormatch.RegexMatcher + OnCategory string + OnSubcategory string + + // compiledTerminationMessage holds the pre-compiled regex from OnTerminationMessage. + // Populated by CompileRules; nil when OnTerminationMessage is nil. + compiledTerminationMessage *regexp.Regexp +} + +// Result is the output of the retry engine evaluation. +type Result struct { + ShouldRetry bool + Reason string +} + +// ValidatePolicy checks that a policy has valid fields. +func ValidatePolicy(p Policy) error { + if p.DefaultAction != ActionFail && p.DefaultAction != ActionRetry { + return fmt.Errorf("DefaultAction must be %q or %q, got %q", ActionFail, ActionRetry, p.DefaultAction) + } + return CompileRules(p.Rules) +} + +// CompileRules validates each rule and compiles its OnTerminationMessage +// regex, if present. Call once when a policy is loaded, not on every evaluation. +func CompileRules(rules []Rule) error { + for i := range rules { + if err := validateRule(i, rules[i]); err != nil { + return err + } + if rules[i].OnTerminationMessage != nil { + re, err := regexp.Compile(rules[i].OnTerminationMessage.Pattern) + if err != nil { + return fmt.Errorf("failed to compile termination message pattern %q in rule %d: %w", + rules[i].OnTerminationMessage.Pattern, i, err) + } + rules[i].compiledTerminationMessage = re + } + } + return nil +} + +func validateRule(index int, rule Rule) error { + if rule.Action != ActionFail && rule.Action != ActionRetry { + return fmt.Errorf("rule %d: Action must be %q or %q, got %q", index, ActionFail, ActionRetry, rule.Action) + } + + hasCategory := rule.OnCategory != "" + hasMatcher := len(rule.OnConditions) > 0 || rule.OnExitCodes != nil || rule.OnTerminationMessage != nil || hasCategory + if !hasMatcher { + return fmt.Errorf("rule %d: must have at least one match field (OnConditions, OnExitCodes, OnTerminationMessage, or OnCategory)", index) + } + if rule.OnSubcategory != "" && !hasCategory { + return fmt.Errorf("rule %d: OnSubcategory requires OnCategory to be set", index) + } + + if rule.OnExitCodes != nil { + op := rule.OnExitCodes.Operator + if op != errormatch.ExitCodeOperatorIn && op != errormatch.ExitCodeOperatorNotIn { + return fmt.Errorf("rule %d: OnExitCodes operator must be %q or %q, got %q", + index, errormatch.ExitCodeOperatorIn, errormatch.ExitCodeOperatorNotIn, op) + } + if len(rule.OnExitCodes.Values) == 0 { + return fmt.Errorf("rule %d: OnExitCodes values must not be empty", index) + } + } + + if rule.OnTerminationMessage != nil && rule.OnTerminationMessage.Pattern == "" { + return fmt.Errorf("rule %d: OnTerminationMessage pattern must not be empty", index) + } + + return nil +} From 418b713f0699e7609af585623366d0f38d0f1690 Mon Sep 17 00:00:00 2001 From: Dejan Zele Pejchev Date: Mon, 30 Mar 2026 15:06:29 +0200 Subject: [PATCH 2/5] Add RetryPolicy CRUD API and armadactl support Introduce RetryPolicy as a first-class API resource with full CRUD operations. This is pure infrastructure with no scheduling behavior changes. Proto: Add RetryPolicy, RetryRule, RetryExitCodeMatcher messages and RetryPolicyService gRPC service with REST gateway bindings on the Submit service. Add retry_policy field to Queue message. Server: Add retrypolicy package with PostgresRetryPolicyRepository (stores serialized proto in retry_policy table) and Server handler with authorization checks. Wire into server startup and register the gRPC service. Add CreateRetryPolicy/DeleteRetryPolicy permissions. Client: Add pkg/client/retrypolicy with Create/Update/Delete/Get/GetAll functions matching the queue client pattern. CLI: Add armadactl commands for create/update/delete/get retry-policy and get retry-policies, all using file-based input for create/update. Add --retry-policy flag to queue create and update commands. Add RetryPolicy as a valid ResourceKind for file-based creation. Signed-off-by: Dejan Zele Pejchev Signed-off-by: Dejan Zele Pejchev --- client/rust/src/gen/api.rs | 432 + .../armada/ArmadaClientSuite.scala | 35 + cmd/armadactl/cmd/commands.go | 5 + cmd/armadactl/cmd/params.go | 7 + cmd/armadactl/cmd/queue.go | 14 + cmd/armadactl/cmd/retrypolicy.go | 123 + internal/armadactl/app.go | 17 +- internal/armadactl/queue.go | 8 + internal/armadactl/retrypolicy.go | 89 + .../migrations/034_create_retry_policy.sql | 5 + internal/scheduler/mocks/api.go | 102 +- .../server/event/conversion/conversions.go | 75 +- .../server/executor/executor_server_test.go | 33 +- internal/server/mocks/generate.go | 1 + .../mocks/mock_retry_policy_repository.go | 108 + internal/server/node/node_test.go | 21 +- internal/server/permissions/permissions.go | 3 + internal/server/queryapi/database/models.go | 5 + internal/server/queue/queue_service_test.go | 25 +- internal/server/retrypolicy/repository.go | 145 + internal/server/retrypolicy/service.go | 141 + internal/server/retrypolicy/service_test.go | 347 + internal/server/server.go | 6 + internal/server/servertest/grpc.go | 17 + internal/server/submit/submit.go | 51 +- internal/server/submit/submit_test.go | 1 + pkg/api/api.swagger.go | 243 + pkg/api/api.swagger.json | 243 + pkg/api/deserialize.go | 70 + pkg/api/deserialize_test.go | 59 + pkg/api/event.pb.go | 349 +- pkg/api/event.proto | 6 + pkg/api/submit.pb.go | 7529 +++++++++++------ pkg/api/submit.pb.gw.go | 465 + pkg/api/submit.proto | 90 + pkg/client/queue/queue.go | 7 +- pkg/client/resource.go | 12 +- pkg/client/retrypolicy/create.go | 35 + pkg/client/retrypolicy/delete.go | 35 + pkg/client/retrypolicy/get.go | 63 + pkg/client/retrypolicy/update.go | 34 + 41 files changed, 8123 insertions(+), 2933 deletions(-) create mode 100644 cmd/armadactl/cmd/retrypolicy.go create mode 100644 internal/armadactl/retrypolicy.go create mode 100644 internal/lookout/schema/migrations/034_create_retry_policy.sql create mode 100644 internal/server/mocks/mock_retry_policy_repository.go create mode 100644 internal/server/retrypolicy/repository.go create mode 100644 internal/server/retrypolicy/service.go create mode 100644 internal/server/retrypolicy/service_test.go create mode 100644 internal/server/servertest/grpc.go create mode 100644 pkg/client/retrypolicy/create.go create mode 100644 pkg/client/retrypolicy/delete.go create mode 100644 pkg/client/retrypolicy/get.go create mode 100644 pkg/client/retrypolicy/update.go diff --git a/client/rust/src/gen/api.rs b/client/rust/src/gen/api.rs index 63a99a34787..1abeffb8e19 100644 --- a/client/rust/src/gen/api.rs +++ b/client/rust/src/gen/api.rs @@ -326,6 +326,8 @@ pub struct Queue { ::prost::alloc::string::String, ::prost::alloc::string::String, >, + #[prost(string, tag = "11")] + pub retry_policy: ::prost::alloc::string::String, } /// Nested message and enum types in `Queue`. pub mod queue { @@ -393,6 +395,63 @@ pub struct PreemptionResult { ::prost::alloc::string::String, >, } +/// RetryPolicy defines rules that determine whether failed jobs should be retried. +/// Operators create policies and assign them to queues by name. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RetryPolicy { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + /// retry_limit is the maximum number of retries after the initial failure. + /// retry_limit: 3 allows up to 3 retries (4 total attempts before terminal + /// failure). 0 means unlimited, subject to the scheduler's global cap. + #[prost(uint32, tag = "2")] + pub retry_limit: u32, + #[prost(enumeration = "RetryAction", tag = "3")] + pub default_action: i32, + #[prost(message, repeated, tag = "4")] + pub rules: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct RetryRule { + #[prost(enumeration = "RetryAction", tag = "1")] + pub action: i32, + #[prost(string, repeated, tag = "2")] + pub on_conditions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, optional, tag = "3")] + pub on_exit_codes: ::core::option::Option, + #[prost(string, tag = "4")] + pub on_termination_message_pattern: ::prost::alloc::string::String, + /// on_category matches against Error.failure_category. When set with on_subcategory, + /// both must match. Mirrors the engine's Rule.OnCategory / Rule.OnSubcategory. + #[prost(string, tag = "5")] + pub on_category: ::prost::alloc::string::String, + #[prost(string, tag = "6")] + pub on_subcategory: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct RetryExitCodeMatcher { + #[prost(enumeration = "ExitCodeOperator", tag = "1")] + pub operator: i32, + #[prost(int32, repeated, tag = "2")] + pub values: ::prost::alloc::vec::Vec, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct RetryPolicyGetRequest { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct RetryPolicyDeleteRequest { + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, +} +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct RetryPolicyListRequest {} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RetryPolicyList { + #[prost(message, repeated, tag = "1")] + pub retry_policies: ::prost::alloc::vec::Vec, +} /// swagger:model #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct QueueGetRequest { @@ -601,6 +660,64 @@ impl JobState { } } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum RetryAction { + Unspecified = 0, + Fail = 1, + Retry = 2, +} +impl RetryAction { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "RETRY_ACTION_UNSPECIFIED", + Self::Fail => "RETRY_ACTION_FAIL", + Self::Retry => "RETRY_ACTION_RETRY", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "RETRY_ACTION_UNSPECIFIED" => Some(Self::Unspecified), + "RETRY_ACTION_FAIL" => Some(Self::Fail), + "RETRY_ACTION_RETRY" => Some(Self::Retry), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum ExitCodeOperator { + Unspecified = 0, + In = 1, + NotIn = 2, +} +impl ExitCodeOperator { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "EXIT_CODE_OPERATOR_UNSPECIFIED", + Self::In => "EXIT_CODE_OPERATOR_IN", + Self::NotIn => "EXIT_CODE_OPERATOR_NOT_IN", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "EXIT_CODE_OPERATOR_UNSPECIFIED" => Some(Self::Unspecified), + "EXIT_CODE_OPERATOR_IN" => Some(Self::In), + "EXIT_CODE_OPERATOR_NOT_IN" => Some(Self::NotIn), + _ => None, + } + } +} /// Generated client implementations. pub mod queue_service_client { #![allow( @@ -934,6 +1051,207 @@ pub mod queue_service_client { } } /// Generated client implementations. +pub mod retry_policy_service_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct RetryPolicyServiceClient { + inner: tonic::client::Grpc, + } + impl RetryPolicyServiceClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl RetryPolicyServiceClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> RetryPolicyServiceClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + std::marker::Send + std::marker::Sync, + { + RetryPolicyServiceClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn create_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.RetryPolicyService/CreateRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.RetryPolicyService", "CreateRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn update_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.RetryPolicyService/UpdateRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.RetryPolicyService", "UpdateRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn delete_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.RetryPolicyService/DeleteRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.RetryPolicyService", "DeleteRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn get_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.RetryPolicyService/GetRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.RetryPolicyService", "GetRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn get_retry_policies( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.RetryPolicyService/GetRetryPolicies", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.RetryPolicyService", "GetRetryPolicies")); + self.inner.unary(req, path, codec).await + } + } +} +/// Generated client implementations. pub mod submit_client { #![allow( unused_variables, @@ -1264,6 +1582,113 @@ pub mod submit_client { req.extensions_mut().insert(GrpcMethod::new("api.Submit", "GetQueues")); self.inner.server_streaming(req, path, codec).await } + pub async fn create_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.Submit/CreateRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.Submit", "CreateRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn update_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.Submit/UpdateRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.Submit", "UpdateRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn delete_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.Submit/DeleteRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.Submit", "DeleteRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn get_retry_policy( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.Submit/GetRetryPolicy", + ); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("api.Submit", "GetRetryPolicy")); + self.inner.unary(req, path, codec).await + } + pub async fn get_retry_policies( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic_prost::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/api.Submit/GetRetryPolicies", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("api.Submit", "GetRetryPolicies")); + self.inner.unary(req, path, codec).await + } pub async fn health( &mut self, request: impl tonic::IntoRequest<()>, @@ -1468,6 +1893,13 @@ pub struct JobFailedEvent { pub failure_category: ::prost::alloc::string::String, #[prost(string, tag = "17")] pub failure_subcategory: ::prost::alloc::string::String, + /// retryable indicates the scheduler emitted this failure for an + /// intermediate (non-terminal) run that will be retried. When true, + /// a subsequent leased/succeeded/failed event for the same job is + /// expected. Default false preserves the prior behavior where every + /// emitted JobFailedEvent was terminal. + #[prost(bool, tag = "18")] + pub retryable: bool, } #[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] pub struct JobPreemptingEvent { diff --git a/client/scala/armada-scala-client/src/test/scala/io/armadaproject/armada/ArmadaClientSuite.scala b/client/scala/armada-scala-client/src/test/scala/io/armadaproject/armada/ArmadaClientSuite.scala index 4a346e47195..1190dc2d37a 100644 --- a/client/scala/armada-scala-client/src/test/scala/io/armadaproject/armada/ArmadaClientSuite.scala +++ b/client/scala/armada-scala-client/src/test/scala/io/armadaproject/armada/ArmadaClientSuite.scala @@ -20,6 +20,11 @@ import api.submit.{ QueueDeleteRequest, QueueGetRequest, QueueList, + RetryPolicy, + RetryPolicyDeleteRequest, + RetryPolicyGetRequest, + RetryPolicyList, + RetryPolicyListRequest, StreamingQueueGetRequest, StreamingQueueMessage, SubmitGrpc @@ -317,6 +322,36 @@ private class SubmitMockServer( ): scala.concurrent.Future[BatchQueueUpdateResponse] = { Future.successful(new BatchQueueUpdateResponse) } + + def createRetryPolicy( + request: RetryPolicy + ): scala.concurrent.Future[com.google.protobuf.empty.Empty] = { + Future.successful(new Empty) + } + + def updateRetryPolicy( + request: RetryPolicy + ): scala.concurrent.Future[com.google.protobuf.empty.Empty] = { + Future.successful(new Empty) + } + + def deleteRetryPolicy( + request: RetryPolicyDeleteRequest + ): scala.concurrent.Future[com.google.protobuf.empty.Empty] = { + Future.successful(new Empty) + } + + def getRetryPolicy( + request: RetryPolicyGetRequest + ): scala.concurrent.Future[RetryPolicy] = { + Future.failed(new StatusRuntimeException(Status.NOT_FOUND)) + } + + def getRetryPolicies( + request: RetryPolicyListRequest + ): scala.concurrent.Future[RetryPolicyList] = { + Future.successful(new RetryPolicyList) + } } private class JobsMockServer( diff --git a/cmd/armadactl/cmd/commands.go b/cmd/armadactl/cmd/commands.go index 35817ed6b35..1e4dad188a4 100644 --- a/cmd/armadactl/cmd/commands.go +++ b/cmd/armadactl/cmd/commands.go @@ -27,6 +27,7 @@ func createCmd(a *armadactl.App) *cobra.Command { } cmd.Flags().Bool("dry-run", false, "Validate the input file and exit without making any changes.") cmd.AddCommand(queueCreateCmd()) + cmd.AddCommand(retryPolicyCreateCmd()) return cmd } @@ -37,6 +38,7 @@ func deleteCmd() *cobra.Command { Long: "Delete Armada resource. Supported: queue", } cmd.AddCommand(queueDeleteCmd()) + cmd.AddCommand(retryPolicyDeleteCmd()) return cmd } @@ -47,6 +49,7 @@ func updateCmd() *cobra.Command { Long: "Update Armada resource. Supported: queue", } cmd.AddCommand(queueUpdateCmd()) + cmd.AddCommand(retryPolicyUpdateCmd()) return cmd } @@ -59,6 +62,8 @@ func getCmd() *cobra.Command { cmd.AddCommand( queueGetCmd(), queuesGetCmd(), + retryPolicyGetCmd(), + retryPolicyGetAllCmd(), getSchedulingReportCmd(armadactl.New()), getQueueSchedulingReportCmd(armadactl.New()), getJobSchedulingReportCmd(armadactl.New()), diff --git a/cmd/armadactl/cmd/params.go b/cmd/armadactl/cmd/params.go index 1bffacfcb84..135474d293d 100644 --- a/cmd/armadactl/cmd/params.go +++ b/cmd/armadactl/cmd/params.go @@ -8,6 +8,7 @@ import ( ce "github.com/armadaproject/armada/pkg/client/executor" cn "github.com/armadaproject/armada/pkg/client/node" cq "github.com/armadaproject/armada/pkg/client/queue" + crp "github.com/armadaproject/armada/pkg/client/retrypolicy" ) // initParams initialises the command parameters, flags, and a configuration file. @@ -33,6 +34,12 @@ func initParams(cmd *cobra.Command, params *armadactl.Params) error { params.QueueAPI.Preempt = cq.Preempt(client.ExtractCommandlineArmadaApiConnectionDetails) params.QueueAPI.Cancel = cq.Cancel(client.ExtractCommandlineArmadaApiConnectionDetails) + params.RetryPolicyAPI.Create = crp.Create(client.ExtractCommandlineArmadaApiConnectionDetails) + params.RetryPolicyAPI.Delete = crp.Delete(client.ExtractCommandlineArmadaApiConnectionDetails) + params.RetryPolicyAPI.Get = crp.Get(client.ExtractCommandlineArmadaApiConnectionDetails) + params.RetryPolicyAPI.GetAll = crp.GetAll(client.ExtractCommandlineArmadaApiConnectionDetails) + params.RetryPolicyAPI.Update = crp.Update(client.ExtractCommandlineArmadaApiConnectionDetails) + params.ExecutorAPI.Cordon = ce.CordonExecutor(client.ExtractCommandlineArmadaApiConnectionDetails) params.ExecutorAPI.Uncordon = ce.UncordonExecutor(client.ExtractCommandlineArmadaApiConnectionDetails) diff --git a/cmd/armadactl/cmd/queue.go b/cmd/armadactl/cmd/queue.go index 92a74995bd1..5db95eec328 100644 --- a/cmd/armadactl/cmd/queue.go +++ b/cmd/armadactl/cmd/queue.go @@ -63,6 +63,11 @@ Job priority is evaluated inside queue, queue has its own priority. Any labels return fmt.Errorf("error converting queue labels to map: %s", err) } + retryPolicyName, err := cmd.Flags().GetString("retry-policy") + if err != nil { + return fmt.Errorf("error reading retry-policy: %s", err) + } + newQueue, err := queue.NewQueue(&api.Queue{ Name: name, PriorityFactor: priorityFactor, @@ -70,6 +75,7 @@ Job priority is evaluated inside queue, queue has its own priority. Any labels GroupOwners: groups, Cordoned: cordoned, Labels: labelsAsMap, + RetryPolicy: retryPolicyName, }) if err != nil { return fmt.Errorf("invalid queue data: %s", err) @@ -83,6 +89,7 @@ Job priority is evaluated inside queue, queue has its own priority. Any labels cmd.Flags().StringSlice("group-owners", []string{}, "Comma separated list of queue group owners, defaults to empty list.") cmd.Flags().Bool("cordon", false, "Used to pause scheduling on specified queue. Defaults to false.") cmd.Flags().StringSliceP("labels", "l", []string{}, "Comma separated list of key-value queue labels, for example: armadaproject.io/submitter=airflow. Defaults to empty list.") + cmd.Flags().String("retry-policy", "", "Name of the retry policy to assign to this queue.") return cmd } @@ -230,6 +237,11 @@ func queueUpdateCmdWithApp(a *armadactl.App) *cobra.Command { return fmt.Errorf("error converting queue labels to map: %s", err) } + retryPolicyName, err := cmd.Flags().GetString("retry-policy") + if err != nil { + return fmt.Errorf("error reading retry-policy: %s", err) + } + newQueue, err := queue.NewQueue(&api.Queue{ Name: name, PriorityFactor: priorityFactor, @@ -237,6 +249,7 @@ func queueUpdateCmdWithApp(a *armadactl.App) *cobra.Command { GroupOwners: groups, Cordoned: cordoned, Labels: labelsAsMap, + RetryPolicy: retryPolicyName, }) if err != nil { return fmt.Errorf("invalid queue data: %s", err) @@ -251,5 +264,6 @@ func queueUpdateCmdWithApp(a *armadactl.App) *cobra.Command { cmd.Flags().StringSlice("group-owners", []string{}, "Comma separated list of queue group owners, defaults to empty list.") cmd.Flags().Bool("cordon", false, "Used to pause scheduling on specified queue. Defaults to false.") cmd.Flags().StringSliceP("labels", "l", []string{}, "Comma separated list of key-value queue labels, for example: armadaproject.io/submitter=airflow. Defaults to empty list.") + cmd.Flags().String("retry-policy", "", "Name of the retry policy to assign to this queue.") return cmd } diff --git a/cmd/armadactl/cmd/retrypolicy.go b/cmd/armadactl/cmd/retrypolicy.go new file mode 100644 index 00000000000..35a629a82c0 --- /dev/null +++ b/cmd/armadactl/cmd/retrypolicy.go @@ -0,0 +1,123 @@ +package cmd + +import ( + "github.com/spf13/cobra" + + "github.com/armadaproject/armada/internal/armadactl" +) + +func retryPolicyCreateCmd() *cobra.Command { + return retryPolicyCreateCmdWithApp(armadactl.New()) +} + +func retryPolicyCreateCmdWithApp(a *armadactl.App) *cobra.Command { + cmd := &cobra.Command{ + Use: "retry-policy", + Short: "Create a retry policy from a YAML/JSON file", + Long: "Create a retry policy that defines rules for whether failed jobs should be retried.", + Args: cobra.NoArgs, + PreRunE: func(cmd *cobra.Command, args []string) error { + return initParams(cmd, a.Params) + }, + RunE: func(cmd *cobra.Command, args []string) error { + filePath, err := cmd.Flags().GetString("file") + if err != nil { + return err + } + return a.CreateRetryPolicyFromFile(filePath) + }, + } + cmd.Flags().StringP("file", "f", "", "Path to YAML/JSON file defining the retry policy.") + if err := cmd.MarkFlagRequired("file"); err != nil { + panic(err) + } + return cmd +} + +func retryPolicyUpdateCmd() *cobra.Command { + return retryPolicyUpdateCmdWithApp(armadactl.New()) +} + +func retryPolicyUpdateCmdWithApp(a *armadactl.App) *cobra.Command { + cmd := &cobra.Command{ + Use: "retry-policy", + Short: "Update a retry policy from a YAML/JSON file", + Long: "Update an existing retry policy with the definition from a YAML/JSON file.", + Args: cobra.NoArgs, + PreRunE: func(cmd *cobra.Command, args []string) error { + return initParams(cmd, a.Params) + }, + RunE: func(cmd *cobra.Command, args []string) error { + filePath, err := cmd.Flags().GetString("file") + if err != nil { + return err + } + return a.UpdateRetryPolicyFromFile(filePath) + }, + } + cmd.Flags().StringP("file", "f", "", "Path to YAML/JSON file defining the retry policy.") + if err := cmd.MarkFlagRequired("file"); err != nil { + panic(err) + } + return cmd +} + +func retryPolicyGetCmd() *cobra.Command { + return retryPolicyGetCmdWithApp(armadactl.New()) +} + +func retryPolicyGetCmdWithApp(a *armadactl.App) *cobra.Command { + cmd := &cobra.Command{ + Use: "retry-policy ", + Short: "Get a retry policy by name", + Long: "Get the definition of a retry policy by its name.", + Args: cobra.ExactArgs(1), + PreRunE: func(cmd *cobra.Command, args []string) error { + return initParams(cmd, a.Params) + }, + RunE: func(cmd *cobra.Command, args []string) error { + return a.GetRetryPolicy(args[0]) + }, + } + return cmd +} + +func retryPolicyGetAllCmd() *cobra.Command { + return retryPolicyGetAllCmdWithApp(armadactl.New()) +} + +func retryPolicyGetAllCmdWithApp(a *armadactl.App) *cobra.Command { + cmd := &cobra.Command{ + Use: "retry-policies", + Short: "List all retry policies", + Long: "List all retry policies defined in the system.", + Args: cobra.NoArgs, + PreRunE: func(cmd *cobra.Command, args []string) error { + return initParams(cmd, a.Params) + }, + RunE: func(cmd *cobra.Command, args []string) error { + return a.GetAllRetryPolicies() + }, + } + return cmd +} + +func retryPolicyDeleteCmd() *cobra.Command { + return retryPolicyDeleteCmdWithApp(armadactl.New()) +} + +func retryPolicyDeleteCmdWithApp(a *armadactl.App) *cobra.Command { + cmd := &cobra.Command{ + Use: "retry-policy ", + Short: "Delete a retry policy by name", + Long: "Delete an existing retry policy by its name.", + Args: cobra.ExactArgs(1), + PreRunE: func(cmd *cobra.Command, args []string) error { + return initParams(cmd, a.Params) + }, + RunE: func(cmd *cobra.Command, args []string) error { + return a.DeleteRetryPolicy(args[0]) + }, + } + return cmd +} diff --git a/internal/armadactl/app.go b/internal/armadactl/app.go index 24caa113a02..962f77f1c1d 100644 --- a/internal/armadactl/app.go +++ b/internal/armadactl/app.go @@ -21,6 +21,7 @@ import ( "github.com/armadaproject/armada/pkg/client/executor" "github.com/armadaproject/armada/pkg/client/node" "github.com/armadaproject/armada/pkg/client/queue" + "github.com/armadaproject/armada/pkg/client/retrypolicy" ) type App struct { @@ -41,6 +42,7 @@ type App struct { type Params struct { ApiConnectionDetails *client.ApiConnectionDetails QueueAPI *QueueAPI + RetryPolicyAPI *RetryPolicyAPI ExecutorAPI *ExecutorAPI NodeAPI *NodeAPI } @@ -69,6 +71,14 @@ type ExecutorAPI struct { PreemptOnExecutor executor.PreemptAPI } +type RetryPolicyAPI struct { + Create retrypolicy.CreateAPI + Delete retrypolicy.DeleteAPI + Get retrypolicy.GetAPI + GetAll retrypolicy.GetAllAPI + Update retrypolicy.UpdateAPI +} + type NodeAPI struct { PreemptOnNode node.PreemptAPI CancelOnNode node.CancelAPI @@ -79,9 +89,10 @@ type NodeAPI struct { func New() *App { return &App{ Params: &Params{ - QueueAPI: &QueueAPI{}, - ExecutorAPI: &ExecutorAPI{}, - NodeAPI: &NodeAPI{}, + QueueAPI: &QueueAPI{}, + RetryPolicyAPI: &RetryPolicyAPI{}, + ExecutorAPI: &ExecutorAPI{}, + NodeAPI: &NodeAPI{}, }, Out: os.Stdout, Random: rand.Reader, diff --git a/internal/armadactl/queue.go b/internal/armadactl/queue.go index b5b7cf75be1..bf802581bc9 100644 --- a/internal/armadactl/queue.go +++ b/internal/armadactl/queue.go @@ -55,6 +55,14 @@ func (a *App) CreateResource(fileName string, dryRun bool) error { if !dryRun { return a.Params.QueueAPI.Create(queue) } + case client.ResourceKindRetryPolicy: + policy := &api.RetryPolicy{} + if err := util.BindJsonOrYaml(fileName, policy); err != nil { + return errors.Errorf("file %s error: %s", fileName, err) + } + if !dryRun { + return a.Params.RetryPolicyAPI.Create(policy) + } default: return errors.Errorf("invalid resource kind: %s", resource.Kind) } diff --git a/internal/armadactl/retrypolicy.go b/internal/armadactl/retrypolicy.go new file mode 100644 index 00000000000..818b9afdb7a --- /dev/null +++ b/internal/armadactl/retrypolicy.go @@ -0,0 +1,89 @@ +package armadactl + +import ( + "fmt" + + "github.com/pkg/errors" + "sigs.k8s.io/yaml" + + "github.com/armadaproject/armada/pkg/api" + "github.com/armadaproject/armada/pkg/client" + "github.com/armadaproject/armada/pkg/client/util" +) + +func (a *App) CreateRetryPolicy(policy *api.RetryPolicy) error { + if err := a.Params.RetryPolicyAPI.Create(policy); err != nil { + return errors.Errorf("error creating retry policy %s: %s", policy.Name, err) + } + fmt.Fprintf(a.Out, "Created retry policy %s\n", policy.Name) + return nil +} + +func (a *App) CreateRetryPolicyFromFile(fileName string) error { + policy := &api.RetryPolicy{} + if err := util.BindJsonOrYaml(fileName, policy); err != nil { + return errors.Errorf("file %s error: %s", fileName, err) + } + return a.CreateRetryPolicy(policy) +} + +func (a *App) UpdateRetryPolicy(policy *api.RetryPolicy) error { + if err := a.Params.RetryPolicyAPI.Update(policy); err != nil { + return errors.Errorf("error updating retry policy %s: %s", policy.Name, err) + } + fmt.Fprintf(a.Out, "Updated retry policy %s\n", policy.Name) + return nil +} + +func (a *App) UpdateRetryPolicyFromFile(fileName string) error { + policy := &api.RetryPolicy{} + if err := util.BindJsonOrYaml(fileName, policy); err != nil { + return errors.Errorf("file %s error: %s", fileName, err) + } + return a.UpdateRetryPolicy(policy) +} + +func (a *App) DeleteRetryPolicy(name string) error { + if err := a.Params.RetryPolicyAPI.Delete(name); err != nil { + return errors.Errorf("error deleting retry policy %s: %s", name, err) + } + fmt.Fprintf(a.Out, "Deleted retry policy %s (or it did not exist)\n", name) + return nil +} + +func (a *App) GetRetryPolicy(name string) error { + policy, err := a.Params.RetryPolicyAPI.Get(name) + if err != nil { + return errors.Errorf("error getting retry policy %s: %s", name, err) + } + b, err := yaml.Marshal(policy) + if err != nil { + return errors.Errorf("error marshalling retry policy %s: %s", name, err) + } + fmt.Fprint(a.Out, retryPolicyHeaderYaml()+string(b)) + return nil +} + +func (a *App) GetAllRetryPolicies() error { + policies, err := a.Params.RetryPolicyAPI.GetAll() + if err != nil { + return errors.Errorf("error getting retry policies: %s", err) + } + b, err := yaml.Marshal(policies) + if err != nil { + return errors.Errorf("error marshalling retry policies: %s", err) + } + fmt.Fprint(a.Out, retryPolicyHeaderYaml()+string(b)) + return nil +} + +func retryPolicyHeaderYaml() string { + b, err := yaml.Marshal(client.Resource{ + Version: client.APIVersionV1, + Kind: client.ResourceKindRetryPolicy, + }) + if err != nil { + panic(err) + } + return string(b) +} diff --git a/internal/lookout/schema/migrations/034_create_retry_policy.sql b/internal/lookout/schema/migrations/034_create_retry_policy.sql new file mode 100644 index 00000000000..3455aceadf0 --- /dev/null +++ b/internal/lookout/schema/migrations/034_create_retry_policy.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS retry_policy +( + name text NOT NULL PRIMARY KEY, + definition bytea NOT NULL +) diff --git a/internal/scheduler/mocks/api.go b/internal/scheduler/mocks/api.go index 53e533daafd..bb291f9daeb 100644 --- a/internal/scheduler/mocks/api.go +++ b/internal/scheduler/mocks/api.go @@ -3,7 +3,7 @@ // // Generated by this command: // -// mockgen -destination=./api.go -package=schedulermocks github.com/armadaproject/armada/pkg/api SubmitClient,Submit_GetQueuesClient +// mockgen -destination=./internal/scheduler/mocks/api.go -package=schedulermocks github.com/armadaproject/armada/pkg/api SubmitClient,Submit_GetQueuesClient // // Package schedulermocks is a generated GoMock package. @@ -124,6 +124,26 @@ func (mr *MockSubmitClientMockRecorder) CreateQueues(ctx, in any, opts ...any) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateQueues", reflect.TypeOf((*MockSubmitClient)(nil).CreateQueues), varargs...) } +// CreateRetryPolicy mocks base method. +func (m *MockSubmitClient) CreateRetryPolicy(ctx context.Context, in *api.RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateRetryPolicy", varargs...) + ret0, _ := ret[0].(*types.Empty) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateRetryPolicy indicates an expected call of CreateRetryPolicy. +func (mr *MockSubmitClientMockRecorder) CreateRetryPolicy(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRetryPolicy", reflect.TypeOf((*MockSubmitClient)(nil).CreateRetryPolicy), varargs...) +} + // DeleteQueue mocks base method. func (m *MockSubmitClient) DeleteQueue(ctx context.Context, in *api.QueueDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) { m.ctrl.T.Helper() @@ -144,6 +164,26 @@ func (mr *MockSubmitClientMockRecorder) DeleteQueue(ctx, in any, opts ...any) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteQueue", reflect.TypeOf((*MockSubmitClient)(nil).DeleteQueue), varargs...) } +// DeleteRetryPolicy mocks base method. +func (m *MockSubmitClient) DeleteRetryPolicy(ctx context.Context, in *api.RetryPolicyDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteRetryPolicy", varargs...) + ret0, _ := ret[0].(*types.Empty) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteRetryPolicy indicates an expected call of DeleteRetryPolicy. +func (mr *MockSubmitClientMockRecorder) DeleteRetryPolicy(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRetryPolicy", reflect.TypeOf((*MockSubmitClient)(nil).DeleteRetryPolicy), varargs...) +} + // GetQueue mocks base method. func (m *MockSubmitClient) GetQueue(ctx context.Context, in *api.QueueGetRequest, opts ...grpc.CallOption) (*api.Queue, error) { m.ctrl.T.Helper() @@ -184,6 +224,46 @@ func (mr *MockSubmitClientMockRecorder) GetQueues(ctx, in any, opts ...any) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueues", reflect.TypeOf((*MockSubmitClient)(nil).GetQueues), varargs...) } +// GetRetryPolicies mocks base method. +func (m *MockSubmitClient) GetRetryPolicies(ctx context.Context, in *api.RetryPolicyListRequest, opts ...grpc.CallOption) (*api.RetryPolicyList, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetRetryPolicies", varargs...) + ret0, _ := ret[0].(*api.RetryPolicyList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRetryPolicies indicates an expected call of GetRetryPolicies. +func (mr *MockSubmitClientMockRecorder) GetRetryPolicies(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRetryPolicies", reflect.TypeOf((*MockSubmitClient)(nil).GetRetryPolicies), varargs...) +} + +// GetRetryPolicy mocks base method. +func (m *MockSubmitClient) GetRetryPolicy(ctx context.Context, in *api.RetryPolicyGetRequest, opts ...grpc.CallOption) (*api.RetryPolicy, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetRetryPolicy", varargs...) + ret0, _ := ret[0].(*api.RetryPolicy) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRetryPolicy indicates an expected call of GetRetryPolicy. +func (mr *MockSubmitClientMockRecorder) GetRetryPolicy(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRetryPolicy", reflect.TypeOf((*MockSubmitClient)(nil).GetRetryPolicy), varargs...) +} + // Health mocks base method. func (m *MockSubmitClient) Health(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (*api.HealthCheckResponse, error) { m.ctrl.T.Helper() @@ -304,6 +384,26 @@ func (mr *MockSubmitClientMockRecorder) UpdateQueues(ctx, in any, opts ...any) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateQueues", reflect.TypeOf((*MockSubmitClient)(nil).UpdateQueues), varargs...) } +// UpdateRetryPolicy mocks base method. +func (m *MockSubmitClient) UpdateRetryPolicy(ctx context.Context, in *api.RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UpdateRetryPolicy", varargs...) + ret0, _ := ret[0].(*types.Empty) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateRetryPolicy indicates an expected call of UpdateRetryPolicy. +func (mr *MockSubmitClientMockRecorder) UpdateRetryPolicy(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRetryPolicy", reflect.TypeOf((*MockSubmitClient)(nil).UpdateRetryPolicy), varargs...) +} + // MockSubmit_GetQueuesClient is a mock of Submit_GetQueuesClient interface. type MockSubmit_GetQueuesClient struct { ctrl *gomock.Controller diff --git a/internal/server/event/conversion/conversions.go b/internal/server/event/conversion/conversions.go index 21e7c6ea8a8..fdfd1939a37 100644 --- a/internal/server/event/conversion/conversions.go +++ b/internal/server/event/conversion/conversions.go @@ -281,14 +281,17 @@ func FromInternalJobRunErrors(queueName string, jobSetName string, time time.Tim func FromInternalJobErrors(queueName string, jobSetName string, time time.Time, e *armadaevents.JobErrors) ([]*api.EventMessage, error) { events := make([]*api.EventMessage, 0) for _, msgErr := range e.GetErrors() { - if !msgErr.Terminal { - continue - } + // Non-terminal errors are surfaced with retryable=true so the stream + // reflects intermediate retry-eligible failures. Only the retry-policy + // engine emits non-terminal JobErrors; all other emitters use + // Terminal=true and behave exactly as before. + retryable := !msgErr.Terminal switch reason := msgErr.Reason.(type) { case *armadaevents.Error_PodError: failed := makeJobFailed(e.JobId, queueName, jobSetName, time, reason) failed.FailureCategory = msgErr.GetFailureCategory() failed.FailureSubcategory = msgErr.GetFailureSubcategory() + failed.Retryable = retryable event := &api.EventMessage{ Events: &api.EventMessage_Failed{ Failed: failed, @@ -299,11 +302,12 @@ func FromInternalJobErrors(queueName string, jobSetName string, time time.Time, event := &api.EventMessage{ Events: &api.EventMessage_Failed{ Failed: &api.JobFailedEvent{ - JobId: e.JobId, - JobSetId: jobSetName, - Queue: queueName, - Created: protoutil.ToTimestamp(time), - Reason: reason.JobRunPreemptedError.Reason, + JobId: e.JobId, + JobSetId: jobSetName, + Queue: queueName, + Created: protoutil.ToTimestamp(time), + Reason: reason.JobRunPreemptedError.Reason, + Retryable: retryable, }, }, } @@ -312,11 +316,12 @@ func FromInternalJobErrors(queueName string, jobSetName string, time time.Time, event := &api.EventMessage{ Events: &api.EventMessage_Failed{ Failed: &api.JobFailedEvent{ - JobId: e.JobId, - JobSetId: jobSetName, - Queue: queueName, - Created: protoutil.ToTimestamp(time), - Reason: reason.MaxRunsExceeded.Message, + JobId: e.JobId, + JobSetId: jobSetName, + Queue: queueName, + Created: protoutil.ToTimestamp(time), + Reason: reason.MaxRunsExceeded.Message, + Retryable: retryable, }, }, } @@ -325,11 +330,12 @@ func FromInternalJobErrors(queueName string, jobSetName string, time time.Time, event := &api.EventMessage{ Events: &api.EventMessage_Failed{ Failed: &api.JobFailedEvent{ - JobId: e.JobId, - JobSetId: jobSetName, - Queue: queueName, - Created: protoutil.ToTimestamp(time), - Reason: reason.GangJobUnschedulable.Message, + JobId: e.JobId, + JobSetId: jobSetName, + Queue: queueName, + Created: protoutil.ToTimestamp(time), + Reason: reason.GangJobUnschedulable.Message, + Retryable: retryable, }, }, } @@ -338,12 +344,13 @@ func FromInternalJobErrors(queueName string, jobSetName string, time time.Time, event := &api.EventMessage{ Events: &api.EventMessage_Failed{ Failed: &api.JobFailedEvent{ - JobId: e.JobId, - JobSetId: jobSetName, - Queue: queueName, - Created: protoutil.ToTimestamp(time), - Reason: reason.JobRejected.Message, - Cause: api.Cause_Rejected, + JobId: e.JobId, + JobSetId: jobSetName, + Queue: queueName, + Created: protoutil.ToTimestamp(time), + Reason: reason.JobRejected.Message, + Cause: api.Cause_Rejected, + Retryable: retryable, }, }, } @@ -352,11 +359,12 @@ func FromInternalJobErrors(queueName string, jobSetName string, time time.Time, event := &api.EventMessage{ Events: &api.EventMessage_Failed{ Failed: &api.JobFailedEvent{ - JobId: e.JobId, - JobSetId: jobSetName, - Queue: queueName, - Created: protoutil.ToTimestamp(time), - Reason: reason.ReconciliationError.Message, + JobId: e.JobId, + JobSetId: jobSetName, + Queue: queueName, + Created: protoutil.ToTimestamp(time), + Reason: reason.ReconciliationError.Message, + Retryable: retryable, }, }, } @@ -366,10 +374,11 @@ func FromInternalJobErrors(queueName string, jobSetName string, time time.Time, event := &api.EventMessage{ Events: &api.EventMessage_Failed{ Failed: &api.JobFailedEvent{ - JobId: e.JobId, - JobSetId: jobSetName, - Queue: queueName, - Created: protoutil.ToTimestamp(time), + JobId: e.JobId, + JobSetId: jobSetName, + Queue: queueName, + Created: protoutil.ToTimestamp(time), + Retryable: retryable, }, }, } diff --git a/internal/server/executor/executor_server_test.go b/internal/server/executor/executor_server_test.go index 6d96b55dead..c50db5f5af6 100644 --- a/internal/server/executor/executor_server_test.go +++ b/internal/server/executor/executor_server_test.go @@ -9,7 +9,6 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" "google.golang.org/grpc/codes" - grpcstatus "google.golang.org/grpc/status" clocktesting "k8s.io/utils/clock/testing" "github.com/armadaproject/armada/internal/common/armadacontext" @@ -20,6 +19,7 @@ import ( protoutil "github.com/armadaproject/armada/internal/common/proto" servermocks "github.com/armadaproject/armada/internal/server/mocks" "github.com/armadaproject/armada/internal/server/permissions" + "github.com/armadaproject/armada/internal/server/servertest" "github.com/armadaproject/armada/pkg/api" "github.com/armadaproject/armada/pkg/controlplaneevents" ) @@ -40,13 +40,6 @@ func newExecutorTestServer(t *testing.T) (*Server, *executorTestMocks) { return s, m } -func requireGrpcCode(t *testing.T, err error, code codes.Code) { - t.Helper() - st, ok := grpcstatus.FromError(err) - require.True(t, ok, "expected gRPC status error") - assert.Equal(t, code, st.Code()) -} - func TestUpsertExecutorSettings_PermissionDenied(t *testing.T) { s, m := newExecutorTestServer(t) grpcCtx := armadacontext.Background() @@ -59,7 +52,7 @@ func TestUpsertExecutorSettings_PermissionDenied(t *testing.T) { _, err := s.UpsertExecutorSettings(grpcCtx, &api.ExecutorSettingsUpsertRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.PermissionDenied) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) } func TestUpsertExecutorSettings_AuthorizeErrorUnavailable(t *testing.T) { @@ -74,7 +67,7 @@ func TestUpsertExecutorSettings_AuthorizeErrorUnavailable(t *testing.T) { _, err := s.UpsertExecutorSettings(grpcCtx, &api.ExecutorSettingsUpsertRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Unavailable) + servertest.RequireGrpcCode(t, err, codes.Unavailable) } func TestUpsertExecutorSettings_ValidationName(t *testing.T) { @@ -125,7 +118,7 @@ func TestUpsertExecutorSettings_PublishErrorInternal(t *testing.T) { _, err := s.UpsertExecutorSettings(grpcCtx, &api.ExecutorSettingsUpsertRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestUpsertExecutorSettings_SuccessPublishesExpectedEvent(t *testing.T) { @@ -186,7 +179,7 @@ func TestDeleteExecutorSettings_PermissionDenied(t *testing.T) { _, err := s.DeleteExecutorSettings(grpcCtx, &api.ExecutorSettingsDeleteRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.PermissionDenied) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) } func TestDeleteExecutorSettings_AuthorizeErrorUnavailable(t *testing.T) { @@ -201,7 +194,7 @@ func TestDeleteExecutorSettings_AuthorizeErrorUnavailable(t *testing.T) { _, err := s.DeleteExecutorSettings(grpcCtx, &api.ExecutorSettingsDeleteRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Unavailable) + servertest.RequireGrpcCode(t, err, codes.Unavailable) } func TestDeleteExecutorSettings_ValidationName(t *testing.T) { @@ -237,7 +230,7 @@ func TestDeleteExecutorSettings_PublishErrorInternal(t *testing.T) { _, err := s.DeleteExecutorSettings(grpcCtx, &api.ExecutorSettingsDeleteRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestDeleteExecutorSettings_SuccessPublishesExpectedEvent(t *testing.T) { @@ -288,7 +281,7 @@ func TestPreemptOnExecutor_PermissionDenied(t *testing.T) { _, err := s.PreemptOnExecutor(grpcCtx, &api.ExecutorPreemptRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.PermissionDenied) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) } func TestPreemptOnExecutor_AuthorizeErrorUnavailable(t *testing.T) { @@ -303,7 +296,7 @@ func TestPreemptOnExecutor_AuthorizeErrorUnavailable(t *testing.T) { _, err := s.PreemptOnExecutor(grpcCtx, &api.ExecutorPreemptRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Unavailable) + servertest.RequireGrpcCode(t, err, codes.Unavailable) } func TestPreemptOnExecutor_ValidationName(t *testing.T) { @@ -339,7 +332,7 @@ func TestPreemptOnExecutor_PublishErrorInternal(t *testing.T) { _, err := s.PreemptOnExecutor(grpcCtx, &api.ExecutorPreemptRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestPreemptOnExecutor_SuccessPublishesExpectedEvent(t *testing.T) { @@ -392,7 +385,7 @@ func TestCancelOnExecutor_PermissionDenied(t *testing.T) { _, err := s.CancelOnExecutor(grpcCtx, &api.ExecutorCancelRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.PermissionDenied) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) } func TestCancelOnExecutor_AuthorizeErrorUnavailable(t *testing.T) { @@ -407,7 +400,7 @@ func TestCancelOnExecutor_AuthorizeErrorUnavailable(t *testing.T) { _, err := s.CancelOnExecutor(grpcCtx, &api.ExecutorCancelRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Unavailable) + servertest.RequireGrpcCode(t, err, codes.Unavailable) } func TestCancelOnExecutor_ValidationName(t *testing.T) { @@ -443,7 +436,7 @@ func TestCancelOnExecutor_PublishErrorInternal(t *testing.T) { _, err := s.CancelOnExecutor(grpcCtx, &api.ExecutorCancelRequest{Name: "executor-1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestCancelOnExecutor_SuccessPublishesExpectedEvent(t *testing.T) { diff --git a/internal/server/mocks/generate.go b/internal/server/mocks/generate.go index 2efeadc2e72..de0fff32137 100644 --- a/internal/server/mocks/generate.go +++ b/internal/server/mocks/generate.go @@ -4,3 +4,4 @@ package mocks //go:generate mockgen -destination=./mock_deduplicator.go -package=mocks "github.com/armadaproject/armada/internal/server/submit" Deduplicator //go:generate mockgen -destination=./mock_authorizer.go -package=mocks "github.com/armadaproject/armada/internal/common/auth" ActionAuthorizer //go:generate mockgen -destination=./mock_repository.go -package=mocks "github.com/armadaproject/armada/internal/server/queue" QueueRepository +//go:generate mockgen -destination=./mock_retry_policy_repository.go -package=mocks "github.com/armadaproject/armada/internal/server/retrypolicy" RetryPolicyRepository diff --git a/internal/server/mocks/mock_retry_policy_repository.go b/internal/server/mocks/mock_retry_policy_repository.go new file mode 100644 index 00000000000..9bab4bac379 --- /dev/null +++ b/internal/server/mocks/mock_retry_policy_repository.go @@ -0,0 +1,108 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/armadaproject/armada/internal/server/retrypolicy (interfaces: RetryPolicyRepository) + +package mocks + +import ( + reflect "reflect" + + armadacontext "github.com/armadaproject/armada/internal/common/armadacontext" + api "github.com/armadaproject/armada/pkg/api" + gomock "go.uber.org/mock/gomock" +) + +// MockRetryPolicyRepository is a mock of RetryPolicyRepository interface. +type MockRetryPolicyRepository struct { + ctrl *gomock.Controller + recorder *MockRetryPolicyRepositoryMockRecorder + isgomock struct{} +} + +// MockRetryPolicyRepositoryMockRecorder is the mock recorder for MockRetryPolicyRepository. +type MockRetryPolicyRepositoryMockRecorder struct { + mock *MockRetryPolicyRepository +} + +// NewMockRetryPolicyRepository creates a new mock instance. +func NewMockRetryPolicyRepository(ctrl *gomock.Controller) *MockRetryPolicyRepository { + mock := &MockRetryPolicyRepository{ctrl: ctrl} + mock.recorder = &MockRetryPolicyRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRetryPolicyRepository) EXPECT() *MockRetryPolicyRepositoryMockRecorder { + return m.recorder +} + +// CreateRetryPolicy mocks base method. +func (m *MockRetryPolicyRepository) CreateRetryPolicy(ctx *armadacontext.Context, policy *api.RetryPolicy) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateRetryPolicy", ctx, policy) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateRetryPolicy indicates an expected call of CreateRetryPolicy. +func (mr *MockRetryPolicyRepositoryMockRecorder) CreateRetryPolicy(ctx, policy any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRetryPolicy", reflect.TypeOf((*MockRetryPolicyRepository)(nil).CreateRetryPolicy), ctx, policy) +} + +// DeleteRetryPolicy mocks base method. +func (m *MockRetryPolicyRepository) DeleteRetryPolicy(ctx *armadacontext.Context, name string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteRetryPolicy", ctx, name) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteRetryPolicy indicates an expected call of DeleteRetryPolicy. +func (mr *MockRetryPolicyRepositoryMockRecorder) DeleteRetryPolicy(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRetryPolicy", reflect.TypeOf((*MockRetryPolicyRepository)(nil).DeleteRetryPolicy), ctx, name) +} + +// GetAllRetryPolicies mocks base method. +func (m *MockRetryPolicyRepository) GetAllRetryPolicies(ctx *armadacontext.Context) ([]*api.RetryPolicy, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAllRetryPolicies", ctx) + ret0, _ := ret[0].([]*api.RetryPolicy) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAllRetryPolicies indicates an expected call of GetAllRetryPolicies. +func (mr *MockRetryPolicyRepositoryMockRecorder) GetAllRetryPolicies(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllRetryPolicies", reflect.TypeOf((*MockRetryPolicyRepository)(nil).GetAllRetryPolicies), ctx) +} + +// GetRetryPolicy mocks base method. +func (m *MockRetryPolicyRepository) GetRetryPolicy(ctx *armadacontext.Context, name string) (*api.RetryPolicy, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRetryPolicy", ctx, name) + ret0, _ := ret[0].(*api.RetryPolicy) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRetryPolicy indicates an expected call of GetRetryPolicy. +func (mr *MockRetryPolicyRepositoryMockRecorder) GetRetryPolicy(ctx, name any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRetryPolicy", reflect.TypeOf((*MockRetryPolicyRepository)(nil).GetRetryPolicy), ctx, name) +} + +// UpdateRetryPolicy mocks base method. +func (m *MockRetryPolicyRepository) UpdateRetryPolicy(ctx *armadacontext.Context, policy *api.RetryPolicy) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateRetryPolicy", ctx, policy) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateRetryPolicy indicates an expected call of UpdateRetryPolicy. +func (mr *MockRetryPolicyRepositoryMockRecorder) UpdateRetryPolicy(ctx, policy any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateRetryPolicy", reflect.TypeOf((*MockRetryPolicyRepository)(nil).UpdateRetryPolicy), ctx, policy) +} diff --git a/internal/server/node/node_test.go b/internal/server/node/node_test.go index 4929053e873..e4c66ab4fce 100644 --- a/internal/server/node/node_test.go +++ b/internal/server/node/node_test.go @@ -9,7 +9,6 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" "google.golang.org/grpc/codes" - grpcstatus "google.golang.org/grpc/status" clocktesting "k8s.io/utils/clock/testing" "github.com/armadaproject/armada/internal/common/armadacontext" @@ -19,6 +18,7 @@ import ( protoutil "github.com/armadaproject/armada/internal/common/proto" servermocks "github.com/armadaproject/armada/internal/server/mocks" "github.com/armadaproject/armada/internal/server/permissions" + "github.com/armadaproject/armada/internal/server/servertest" "github.com/armadaproject/armada/pkg/api" "github.com/armadaproject/armada/pkg/controlplaneevents" ) @@ -39,13 +39,6 @@ func newTestServer(t *testing.T) (*Server, *testMocks) { return s, m } -func requireGrpcCode(t *testing.T, err error, code codes.Code) { - t.Helper() - st, ok := grpcstatus.FromError(err) - require.True(t, ok, "expected gRPC status error") - assert.Equal(t, code, st.Code()) -} - func TestPreemptOnNode_PermissionDenied(t *testing.T) { s, m := newTestServer(t) ctx := armadacontext.Background() @@ -58,7 +51,7 @@ func TestPreemptOnNode_PermissionDenied(t *testing.T) { _, err := s.PreemptOnNode(ctx, &api.NodePreemptRequest{Name: "executor-1", Executor: "executor-id"}) require.Error(t, err) - requireGrpcCode(t, err, codes.PermissionDenied) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) } func TestPreemptOnNode_AuthorizeErrorUnavailable(t *testing.T) { @@ -73,7 +66,7 @@ func TestPreemptOnNode_AuthorizeErrorUnavailable(t *testing.T) { _, err := s.PreemptOnNode(ctx, &api.NodePreemptRequest{Name: "executor-1", Executor: "executor-id"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestPreemptOnNode_Validation(t *testing.T) { @@ -109,7 +102,7 @@ func TestPreemptOnNode_PublishErrorInternal(t *testing.T) { _, err := s.PreemptOnNode(ctx, &api.NodePreemptRequest{Name: "executor-1", Executor: "executor-id"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestPreemptOnNode_SuccessPublishesExpectedEvent(t *testing.T) { @@ -168,7 +161,7 @@ func TestCancelOnNode_PermissionDenied(t *testing.T) { _, err := s.CancelOnNode(ctx, &api.NodeCancelRequest{Name: "executor-1", Executor: "executor-id"}) require.Error(t, err) - requireGrpcCode(t, err, codes.PermissionDenied) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) } func TestCancelOnNode_AuthorizeErrorUnavailable(t *testing.T) { @@ -183,7 +176,7 @@ func TestCancelOnNode_AuthorizeErrorUnavailable(t *testing.T) { _, err := s.CancelOnNode(ctx, &api.NodeCancelRequest{Name: "executor-1", Executor: "executor-id"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestCancelOnNode_Validation(t *testing.T) { @@ -219,7 +212,7 @@ func TestCancelOnNode_PublishErrorInternal(t *testing.T) { _, err := s.CancelOnNode(ctx, &api.NodeCancelRequest{Name: "executor-1", Executor: "executor-id"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestCancelOnNode_SuccessPublishesExpectedEvent(t *testing.T) { diff --git a/internal/server/permissions/permissions.go b/internal/server/permissions/permissions.go index 21b06426b26..3a11183c4ad 100644 --- a/internal/server/permissions/permissions.go +++ b/internal/server/permissions/permissions.go @@ -17,4 +17,7 @@ const ( CordonNodes = "cordon_nodes" ExecuteJobs = "execute_jobs" UpdateExecutorSettings = "update_executor_settings" + CreateRetryPolicy = "create_retry_policy" + UpdateRetryPolicy = "update_retry_policy" + DeleteRetryPolicy = "delete_retry_policy" ) diff --git a/internal/server/queryapi/database/models.go b/internal/server/queryapi/database/models.go index 9aca2755812..8e8fdf8f5a2 100644 --- a/internal/server/queryapi/database/models.go +++ b/internal/server/queryapi/database/models.go @@ -73,3 +73,8 @@ type Queue struct { Name string `db:"name"` Definition []byte `db:"definition"` } + +type RetryPolicy struct { + Name string `db:"name"` + Definition []byte `db:"definition"` +} diff --git a/internal/server/queue/queue_service_test.go b/internal/server/queue/queue_service_test.go index f0dc7ff2885..71497e279f0 100644 --- a/internal/server/queue/queue_service_test.go +++ b/internal/server/queue/queue_service_test.go @@ -12,7 +12,6 @@ import ( "go.uber.org/mock/gomock" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" - grpcstatus "google.golang.org/grpc/status" clocktesting "k8s.io/utils/clock/testing" "github.com/armadaproject/armada/internal/common/armadacontext" @@ -23,6 +22,7 @@ import ( protoutil "github.com/armadaproject/armada/internal/common/proto" servermocks "github.com/armadaproject/armada/internal/server/mocks" "github.com/armadaproject/armada/internal/server/permissions" + "github.com/armadaproject/armada/internal/server/servertest" "github.com/armadaproject/armada/pkg/api" "github.com/armadaproject/armada/pkg/client/queue" "github.com/armadaproject/armada/pkg/controlplaneevents" @@ -46,13 +46,6 @@ func newTestQueueServer(t *testing.T) (*Server, *queueServiceTestMocks) { return s, m } -func requireGrpcCode(t *testing.T, err error, code codes.Code) { - t.Helper() - st, ok := grpcstatus.FromError(err) - require.True(t, ok, "expected gRPC status error") - assert.Equal(t, code, st.Code()) -} - func TestCreateQueue_PermissionDenied(t *testing.T) { s, m := newTestQueueServer(t) ctx := armadacontext.Background() @@ -65,7 +58,7 @@ func TestCreateQueue_PermissionDenied(t *testing.T) { _, err := s.CreateQueue(ctx, &api.Queue{Name: "q1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.PermissionDenied) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) } func TestCreateQueue_AuthorizeErrorUnavailable(t *testing.T) { @@ -80,7 +73,7 @@ func TestCreateQueue_AuthorizeErrorUnavailable(t *testing.T) { _, err := s.CreateQueue(ctx, &api.Queue{Name: "q1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.Unavailable) + servertest.RequireGrpcCode(t, err, codes.Unavailable) } func TestCreateQueue_DefaultsUserOwnerFromPrincipal(t *testing.T) { @@ -132,7 +125,7 @@ func TestCreateQueue_ValidationInvalidArgument(t *testing.T) { _, err := s.CreateQueue(ctx, &api.Queue{Name: "q1", PriorityFactor: 1, Labels: map[string]string{"k": ""}}) require.Error(t, err) - requireGrpcCode(t, err, codes.InvalidArgument) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) } func TestCreateQueue_AlreadyExists(t *testing.T) { @@ -153,7 +146,7 @@ func TestCreateQueue_AlreadyExists(t *testing.T) { _, err := s.CreateQueue(ctx, &api.Queue{Name: "q1", PriorityFactor: 1}) require.Error(t, err) - requireGrpcCode(t, err, codes.AlreadyExists) + servertest.RequireGrpcCode(t, err, codes.AlreadyExists) } func TestUpdateQueue_NotFound(t *testing.T) { @@ -174,7 +167,7 @@ func TestUpdateQueue_NotFound(t *testing.T) { _, err := s.UpdateQueue(ctx, &api.Queue{Name: "q1", PriorityFactor: 1}) require.Error(t, err) - requireGrpcCode(t, err, codes.NotFound) + servertest.RequireGrpcCode(t, err, codes.NotFound) } func TestDeleteQueue_RepoErrorInvalidArgument(t *testing.T) { @@ -195,7 +188,7 @@ func TestDeleteQueue_RepoErrorInvalidArgument(t *testing.T) { _, err := s.DeleteQueue(ctx, &api.QueueDeleteRequest{Name: "q1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.InvalidArgument) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) } func TestGetQueue_NotFound(t *testing.T) { @@ -210,7 +203,7 @@ func TestGetQueue_NotFound(t *testing.T) { _, err := s.GetQueue(ctx, &api.QueueGetRequest{Name: "q1"}) require.Error(t, err) - requireGrpcCode(t, err, codes.NotFound) + servertest.RequireGrpcCode(t, err, codes.NotFound) } type fakeQueueStream struct { @@ -289,7 +282,7 @@ func TestCancelOnQueue_PublishErrorInternal(t *testing.T) { _, err := s.CancelOnQueue(ctx, &api.QueueCancelRequest{Name: "q1", JobStates: []api.JobState{api.JobState_RUNNING}}) require.Error(t, err) - requireGrpcCode(t, err, codes.Internal) + servertest.RequireGrpcCode(t, err, codes.Internal) } func TestCancelOnQueue_SuccessPublishesExpectedEvent(t *testing.T) { diff --git a/internal/server/retrypolicy/repository.go b/internal/server/retrypolicy/repository.go new file mode 100644 index 00000000000..4ae70dbf05f --- /dev/null +++ b/internal/server/retrypolicy/repository.go @@ -0,0 +1,145 @@ +package retrypolicy + +import ( + "fmt" + + "github.com/gogo/protobuf/proto" + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" + "github.com/pkg/errors" + + "github.com/armadaproject/armada/internal/common/armadacontext" + "github.com/armadaproject/armada/pkg/api" +) + +type ErrRetryPolicyNotFound struct { + Name string +} + +func (err *ErrRetryPolicyNotFound) Error() string { + return fmt.Sprintf("could not find retry policy %q", err.Name) +} + +type ErrRetryPolicyAlreadyExists struct { + Name string +} + +func (err *ErrRetryPolicyAlreadyExists) Error() string { + return fmt.Sprintf("retry policy %s already exists", err.Name) +} + +type RetryPolicyRepository interface { + GetAllRetryPolicies(ctx *armadacontext.Context) ([]*api.RetryPolicy, error) + GetRetryPolicy(ctx *armadacontext.Context, name string) (*api.RetryPolicy, error) + CreateRetryPolicy(ctx *armadacontext.Context, policy *api.RetryPolicy) error + UpdateRetryPolicy(ctx *armadacontext.Context, policy *api.RetryPolicy) error + DeleteRetryPolicy(ctx *armadacontext.Context, name string) error +} + +type PostgresRetryPolicyRepository struct { + db *pgxpool.Pool +} + +func NewPostgresRetryPolicyRepository(db *pgxpool.Pool) *PostgresRetryPolicyRepository { + return &PostgresRetryPolicyRepository{db: db} +} + +func (r *PostgresRetryPolicyRepository) GetAllRetryPolicies(ctx *armadacontext.Context) ([]*api.RetryPolicy, error) { + rows, err := r.db.Query(ctx, "SELECT definition FROM retry_policy ORDER BY name") + if err != nil { + return nil, errors.WithStack(err) + } + defer rows.Close() + + var policies []*api.RetryPolicy + for rows.Next() { + var definitionBytes []byte + err := rows.Scan(&definitionBytes) + if err != nil { + return nil, errors.WithStack(err) + } + policy, err := unmarshalRetryPolicy(definitionBytes) + if err != nil { + return nil, errors.WithStack(err) + } + policies = append(policies, policy) + } + + if err := rows.Err(); err != nil { + return nil, errors.WithStack(err) + } + return policies, nil +} + +func (r *PostgresRetryPolicyRepository) GetRetryPolicy(ctx *armadacontext.Context, name string) (*api.RetryPolicy, error) { + var definitionBytes []byte + query := "SELECT definition FROM retry_policy WHERE name = $1" + + err := r.db.QueryRow(ctx, query, name).Scan(&definitionBytes) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return nil, &ErrRetryPolicyNotFound{Name: name} + } + return nil, errors.WithStack(err) + } + + policy, err := unmarshalRetryPolicy(definitionBytes) + if err != nil { + return nil, errors.WithStack(err) + } + return policy, nil +} + +func (r *PostgresRetryPolicyRepository) CreateRetryPolicy(ctx *armadacontext.Context, policy *api.RetryPolicy) error { + data, err := proto.Marshal(policy) + if err != nil { + return errors.WithStack(err) + } + + query := "INSERT INTO retry_policy (name, definition) VALUES ($1, $2) ON CONFLICT (name) DO NOTHING" + result, err := r.db.Exec(ctx, query, policy.Name, data) + if err != nil { + return errors.WithStack(err) + } + if result.RowsAffected() == 0 { + return &ErrRetryPolicyAlreadyExists{Name: policy.Name} + } + return nil +} + +func (r *PostgresRetryPolicyRepository) UpdateRetryPolicy(ctx *armadacontext.Context, policy *api.RetryPolicy) error { + data, err := proto.Marshal(policy) + if err != nil { + return errors.WithStack(err) + } + + query := "UPDATE retry_policy SET definition = $2 WHERE name = $1" + result, err := r.db.Exec(ctx, query, policy.Name, data) + if err != nil { + return errors.WithStack(err) + } + if result.RowsAffected() == 0 { + return &ErrRetryPolicyNotFound{Name: policy.Name} + } + return nil +} + +// DeleteRetryPolicy removes a retry policy by name. +// Deletes are intentionally idempotent - deleting a non-existent policy is a no-op, +// consistent with DeleteQueue in queue_repository.go. +func (r *PostgresRetryPolicyRepository) DeleteRetryPolicy(ctx *armadacontext.Context, name string) error { + query := "DELETE FROM retry_policy WHERE name = $1" + _, err := r.db.Exec(ctx, query, name) + if err != nil { + return errors.WithStack(err) + } + return nil +} + +func unmarshalRetryPolicy(definitionBytes []byte) (*api.RetryPolicy, error) { + policy := &api.RetryPolicy{} + if err := proto.Unmarshal(definitionBytes, policy); err != nil { + return nil, err + } + return policy, nil +} diff --git a/internal/server/retrypolicy/service.go b/internal/server/retrypolicy/service.go new file mode 100644 index 00000000000..3f39185da02 --- /dev/null +++ b/internal/server/retrypolicy/service.go @@ -0,0 +1,141 @@ +package retrypolicy + +import ( + "context" + + "github.com/gogo/protobuf/types" + "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/armadaproject/armada/internal/common/armadacontext" + "github.com/armadaproject/armada/internal/common/armadaerrors" + "github.com/armadaproject/armada/internal/common/auth" + "github.com/armadaproject/armada/internal/scheduler/retry" + "github.com/armadaproject/armada/internal/server/permissions" + "github.com/armadaproject/armada/pkg/api" +) + +type Server struct { + repository RetryPolicyRepository + authorizer auth.ActionAuthorizer +} + +func NewServer(repository RetryPolicyRepository, authorizer auth.ActionAuthorizer) *Server { + return &Server{ + repository: repository, + authorizer: authorizer, + } +} + +func (s *Server) CreateRetryPolicy(grpcCtx context.Context, req *api.RetryPolicy) (*types.Empty, error) { + ctx := armadacontext.FromGrpcCtx(grpcCtx) + err := s.authorizer.AuthorizeAction(ctx, permissions.CreateRetryPolicy) + var ep *armadaerrors.ErrUnauthorized + if errors.As(err, &ep) { + return nil, status.Errorf(codes.PermissionDenied, "error creating retry policy %s: %s", req.Name, ep) + } else if err != nil { + return nil, status.Errorf(codes.Unavailable, "error checking permissions: %s", err) + } + + if req.Name == "" { + return nil, status.Errorf(codes.InvalidArgument, "retry policy name must not be empty") + } + + // Reject invalid policies up front. The cache loader runs the same + // validation and silently drops bad policies, so without this check the + // operator gets a 200 OK and only sees the policy fail to install later. + if _, err := retry.ConvertPolicy(req); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid retry policy: %s", err) + } + + err = s.repository.CreateRetryPolicy(ctx, req) + var ea *ErrRetryPolicyAlreadyExists + if errors.As(err, &ea) { + return nil, status.Errorf(codes.AlreadyExists, "error creating retry policy: %s", err) + } else if err != nil { + return nil, status.Errorf(codes.Unavailable, "error creating retry policy: %s", err) + } + + return &types.Empty{}, nil +} + +func (s *Server) UpdateRetryPolicy(grpcCtx context.Context, req *api.RetryPolicy) (*types.Empty, error) { + ctx := armadacontext.FromGrpcCtx(grpcCtx) + err := s.authorizer.AuthorizeAction(ctx, permissions.UpdateRetryPolicy) + var ep *armadaerrors.ErrUnauthorized + if errors.As(err, &ep) { + return nil, status.Errorf(codes.PermissionDenied, "error updating retry policy %s: %s", req.Name, ep) + } else if err != nil { + return nil, status.Errorf(codes.Unavailable, "error checking permissions: %s", err) + } + + if req.Name == "" { + return nil, status.Errorf(codes.InvalidArgument, "retry policy name must not be empty") + } + + if _, err := retry.ConvertPolicy(req); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid retry policy: %s", err) + } + + err = s.repository.UpdateRetryPolicy(ctx, req) + var enf *ErrRetryPolicyNotFound + if errors.As(err, &enf) { + return nil, status.Errorf(codes.NotFound, "error: %s", err) + } else if err != nil { + return nil, status.Errorf(codes.Unavailable, "error updating retry policy %q: %s", req.Name, err) + } + + return &types.Empty{}, nil +} + +func (s *Server) DeleteRetryPolicy(grpcCtx context.Context, req *api.RetryPolicyDeleteRequest) (*types.Empty, error) { + ctx := armadacontext.FromGrpcCtx(grpcCtx) + err := s.authorizer.AuthorizeAction(ctx, permissions.DeleteRetryPolicy) + var ep *armadaerrors.ErrUnauthorized + if errors.As(err, &ep) { + return nil, status.Errorf(codes.PermissionDenied, "error deleting retry policy %s: %s", req.Name, ep) + } else if err != nil { + return nil, status.Errorf(codes.Unavailable, "error checking permissions: %s", err) + } + + if req.Name == "" { + return nil, status.Errorf(codes.InvalidArgument, "retry policy name must not be empty") + } + + err = s.repository.DeleteRetryPolicy(ctx, req.Name) + if err != nil { + return nil, status.Errorf(codes.Unavailable, "error deleting retry policy %s: %s", req.Name, err) + } + return &types.Empty{}, nil +} + +// GetRetryPolicy returns a single retry policy by name. +// Read access is intentionally unauthenticated, consistent with GetQueue in queue_service.go. +func (s *Server) GetRetryPolicy(grpcCtx context.Context, req *api.RetryPolicyGetRequest) (*api.RetryPolicy, error) { + ctx := armadacontext.FromGrpcCtx(grpcCtx) + + if req.Name == "" { + return nil, status.Errorf(codes.InvalidArgument, "retry policy name must not be empty") + } + + policy, err := s.repository.GetRetryPolicy(ctx, req.Name) + var enf *ErrRetryPolicyNotFound + if errors.As(err, &enf) { + return nil, status.Errorf(codes.NotFound, "error: %s", err) + } else if err != nil { + return nil, status.Errorf(codes.Unavailable, "error getting retry policy %q: %s", req.Name, err) + } + return policy, nil +} + +// GetRetryPolicies returns all retry policies. +// Read access is intentionally unauthenticated, consistent with GetQueue in queue_service.go. +func (s *Server) GetRetryPolicies(grpcCtx context.Context, _ *api.RetryPolicyListRequest) (*api.RetryPolicyList, error) { + ctx := armadacontext.FromGrpcCtx(grpcCtx) + policies, err := s.repository.GetAllRetryPolicies(ctx) + if err != nil { + return nil, status.Errorf(codes.Unavailable, "error getting retry policies: %s", err) + } + return &api.RetryPolicyList{RetryPolicies: policies}, nil +} diff --git a/internal/server/retrypolicy/service_test.go b/internal/server/retrypolicy/service_test.go new file mode 100644 index 00000000000..2e3a9da1eaf --- /dev/null +++ b/internal/server/retrypolicy/service_test.go @@ -0,0 +1,347 @@ +package retrypolicy + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + "google.golang.org/grpc/codes" + + "github.com/armadaproject/armada/internal/common/armadacontext" + "github.com/armadaproject/armada/internal/common/armadaerrors" + "github.com/armadaproject/armada/internal/common/auth/permission" + servermocks "github.com/armadaproject/armada/internal/server/mocks" + "github.com/armadaproject/armada/internal/server/permissions" + "github.com/armadaproject/armada/internal/server/servertest" + "github.com/armadaproject/armada/pkg/api" +) + +type testMocks struct { + authorizer *servermocks.MockActionAuthorizer + repo *servermocks.MockRetryPolicyRepository +} + +func newTestServer(t *testing.T) (*Server, *testMocks) { + t.Helper() + ctrl := gomock.NewController(t) + m := &testMocks{ + authorizer: servermocks.NewMockActionAuthorizer(ctrl), + repo: servermocks.NewMockRetryPolicyRepository(ctrl), + } + s := NewServer(m.repo, m.authorizer) + return s, m +} + +// validPolicy returns a minimal proto that passes retry.ConvertPolicy, so tests +// targeting downstream behaviour aren't rejected at the upfront validation step. +func validPolicy(name string) *api.RetryPolicy { + return &api.RetryPolicy{ + Name: name, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + } +} + +func TestCreateRetryPolicy_PermissionDenied(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.CreateRetryPolicy)). + Return(&armadaerrors.ErrUnauthorized{Principal: "alice", Permission: "create_retry_policy"}). + Times(1) + + _, err := s.CreateRetryPolicy(ctx, &api.RetryPolicy{Name: "p1"}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) +} + +func TestCreateRetryPolicy_AuthorizeErrorUnavailable(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.CreateRetryPolicy)). + Return(errors.New("authorizer down")). + Times(1) + + _, err := s.CreateRetryPolicy(ctx, &api.RetryPolicy{Name: "p1"}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.Unavailable) +} + +func TestCreateRetryPolicy_EmptyNameInvalidArgument(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.CreateRetryPolicy)). + Return(nil). + Times(1) + + _, err := s.CreateRetryPolicy(ctx, &api.RetryPolicy{Name: ""}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) +} + +func TestCreateRetryPolicy_AlreadyExists(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.CreateRetryPolicy)). + Return(nil). + Times(1) + + m.repo. + EXPECT(). + CreateRetryPolicy(gomock.Any(), gomock.Any()). + Return(&ErrRetryPolicyAlreadyExists{Name: "p1"}). + Times(1) + + _, err := s.CreateRetryPolicy(ctx, validPolicy("p1")) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.AlreadyExists) +} + +func TestCreateRetryPolicy_InvalidPolicyRejected(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.CreateRetryPolicy)). + Return(nil). + Times(1) + + // DefaultAction defaults to RETRY_ACTION_UNSPECIFIED, which ConvertPolicy + // rejects. No repo expectation is set: gomock fails if the repository is + // called. + _, err := s.CreateRetryPolicy(ctx, &api.RetryPolicy{Name: "p1"}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) +} + +func TestCreateRetryPolicy_Success(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.CreateRetryPolicy)). + Return(nil). + Times(1) + + m.repo. + EXPECT(). + CreateRetryPolicy(gomock.Any(), gomock.Any()). + Return(nil). + Times(1) + + policy := validPolicy("p1") + policy.RetryLimit = 3 + _, err := s.CreateRetryPolicy(ctx, policy) + require.NoError(t, err) +} + +func TestUpdateRetryPolicy_PermissionDenied(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.UpdateRetryPolicy)). + Return(&armadaerrors.ErrUnauthorized{Principal: "alice", Permission: "update_retry_policy"}). + Times(1) + + _, err := s.UpdateRetryPolicy(ctx, &api.RetryPolicy{Name: "p1"}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) +} + +func TestUpdateRetryPolicy_EmptyName(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.UpdateRetryPolicy)). + Return(nil). + Times(1) + + _, err := s.UpdateRetryPolicy(ctx, &api.RetryPolicy{Name: ""}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) +} + +func TestUpdateRetryPolicy_NotFound(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.UpdateRetryPolicy)). + Return(nil). + Times(1) + + m.repo. + EXPECT(). + UpdateRetryPolicy(gomock.Any(), gomock.Any()). + Return(&ErrRetryPolicyNotFound{Name: "p1"}). + Times(1) + + _, err := s.UpdateRetryPolicy(ctx, validPolicy("p1")) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.NotFound) +} + +func TestUpdateRetryPolicy_InvalidPolicyRejected(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.UpdateRetryPolicy)). + Return(nil). + Times(1) + + _, err := s.UpdateRetryPolicy(ctx, &api.RetryPolicy{Name: "p1"}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) +} + +func TestUpdateRetryPolicy_Success(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.UpdateRetryPolicy)). + Return(nil). + Times(1) + + m.repo. + EXPECT(). + UpdateRetryPolicy(gomock.Any(), gomock.Any()). + Return(nil). + Times(1) + + policy := validPolicy("p1") + policy.RetryLimit = 5 + _, err := s.UpdateRetryPolicy(ctx, policy) + require.NoError(t, err) +} + +func TestDeleteRetryPolicy_EmptyName(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.DeleteRetryPolicy)). + Return(nil). + Times(1) + + _, err := s.DeleteRetryPolicy(ctx, &api.RetryPolicyDeleteRequest{Name: ""}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) +} + +func TestDeleteRetryPolicy_PermissionDenied(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.DeleteRetryPolicy)). + Return(&armadaerrors.ErrUnauthorized{Principal: "alice", Permission: "delete_retry_policy"}). + Times(1) + + _, err := s.DeleteRetryPolicy(ctx, &api.RetryPolicyDeleteRequest{Name: "p1"}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.PermissionDenied) +} + +func TestDeleteRetryPolicy_Success(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.authorizer. + EXPECT(). + AuthorizeAction(ctx, permission.Permission(permissions.DeleteRetryPolicy)). + Return(nil). + Times(1) + + m.repo. + EXPECT(). + DeleteRetryPolicy(gomock.Any(), "p1"). + Return(nil). + Times(1) + + _, err := s.DeleteRetryPolicy(ctx, &api.RetryPolicyDeleteRequest{Name: "p1"}) + require.NoError(t, err) +} + +func TestGetRetryPolicy_EmptyName(t *testing.T) { + s, _ := newTestServer(t) + ctx := armadacontext.Background() + + _, err := s.GetRetryPolicy(ctx, &api.RetryPolicyGetRequest{Name: ""}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.InvalidArgument) +} + +func TestGetRetryPolicy_NotFound(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + m.repo. + EXPECT(). + GetRetryPolicy(gomock.Any(), "p1"). + Return(nil, &ErrRetryPolicyNotFound{Name: "p1"}). + Times(1) + + _, err := s.GetRetryPolicy(ctx, &api.RetryPolicyGetRequest{Name: "p1"}) + require.Error(t, err) + servertest.RequireGrpcCode(t, err, codes.NotFound) +} + +func TestGetRetryPolicy_Success(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + expected := &api.RetryPolicy{Name: "p1", RetryLimit: 5} + m.repo. + EXPECT(). + GetRetryPolicy(gomock.Any(), "p1"). + Return(expected, nil). + Times(1) + + result, err := s.GetRetryPolicy(ctx, &api.RetryPolicyGetRequest{Name: "p1"}) + require.NoError(t, err) + assert.Equal(t, expected, result) +} + +func TestGetRetryPolicies_Success(t *testing.T) { + s, m := newTestServer(t) + ctx := armadacontext.Background() + + expected := []*api.RetryPolicy{ + {Name: "p1", RetryLimit: 3}, + {Name: "p2", RetryLimit: 5}, + } + m.repo. + EXPECT(). + GetAllRetryPolicies(gomock.Any()). + Return(expected, nil). + Times(1) + + result, err := s.GetRetryPolicies(ctx, &api.RetryPolicyListRequest{}) + require.NoError(t, err) + assert.Equal(t, expected, result.RetryPolicies) +} diff --git a/internal/server/server.go b/internal/server/server.go index f6411234aa2..aa527731a9d 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -31,6 +31,7 @@ import ( "github.com/armadaproject/armada/internal/server/node" "github.com/armadaproject/armada/internal/server/queryapi" "github.com/armadaproject/armada/internal/server/queue" + "github.com/armadaproject/armada/internal/server/retrypolicy" "github.com/armadaproject/armada/internal/server/submit" "github.com/armadaproject/armada/pkg/api" "github.com/armadaproject/armada/pkg/api/schedulerobjects" @@ -166,8 +167,12 @@ func Serve(ctx *armadacontext.Context, config *configuration.ArmadaConfig, healt queueServer := queue.NewServer(controlPlaneEventsPublisher, queueRepository, authorizer) + retryPolicyRepo := retrypolicy.NewPostgresRetryPolicyRepository(dbPool) + retryPolicyServer := retrypolicy.NewServer(retryPolicyRepo, authorizer) + submitServer := submit.NewServer( queueServer, + retryPolicyServer, jobSetEventsPublisher, queueCache, config.Submission, @@ -194,6 +199,7 @@ func Serve(ctx *armadacontext.Context, config *configuration.ArmadaConfig, healt api.RegisterSubmitServer(grpcServer, submitServer) api.RegisterEventServer(grpcServer, eventServer) api.RegisterQueueServiceServer(grpcServer, queueServer) + api.RegisterRetryPolicyServiceServer(grpcServer, retryPolicyServer) api.RegisterExecutorServer(grpcServer, executorServer) api.RegisterNodeServer(grpcServer, nodeServer) diff --git a/internal/server/servertest/grpc.go b/internal/server/servertest/grpc.go new file mode 100644 index 00000000000..0c19679847a --- /dev/null +++ b/internal/server/servertest/grpc.go @@ -0,0 +1,17 @@ +package servertest + +import ( + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// RequireGrpcCode asserts that err is a gRPC status error with the given code. +func RequireGrpcCode(t *testing.T, err error, code codes.Code) { + t.Helper() + st, ok := status.FromError(err) + require.True(t, ok, "expected gRPC status error") + require.Equal(t, code, st.Code()) +} diff --git a/internal/server/submit/submit.go b/internal/server/submit/submit.go index 80dc618da9b..3938b105b68 100644 --- a/internal/server/submit/submit.go +++ b/internal/server/submit/submit.go @@ -30,12 +30,13 @@ import ( // Server is a service that accepts API calls according to the original Armada submit API and publishes messages // to Pulsar based on those calls. type Server struct { - queueService api.QueueServiceServer - publisher pulsarutils.Publisher[*armadaevents.EventSequence] - queueCache armadaqueue.ReadOnlyQueueRepository - submissionConfig configuration.SubmissionConfig - deduplicator Deduplicator - authorizer auth.ActionAuthorizer + queueService api.QueueServiceServer + retryPolicyService api.RetryPolicyServiceServer + publisher pulsarutils.Publisher[*armadaevents.EventSequence] + queueCache armadaqueue.ReadOnlyQueueRepository + submissionConfig configuration.SubmissionConfig + deduplicator Deduplicator + authorizer auth.ActionAuthorizer // Below are used only for testing clock clock.Clock idGenerator func() string @@ -43,6 +44,7 @@ type Server struct { func NewServer( queueService api.QueueServiceServer, + retryPolicyService api.RetryPolicyServiceServer, publisher pulsarutils.Publisher[*armadaevents.EventSequence], queueCache armadaqueue.ReadOnlyQueueRepository, submissionConfig configuration.SubmissionConfig, @@ -50,14 +52,15 @@ func NewServer( authorizer auth.ActionAuthorizer, ) *Server { return &Server{ - queueService: queueService, - publisher: publisher, - queueCache: queueCache, - submissionConfig: submissionConfig, - deduplicator: deduplicator, - authorizer: authorizer, - clock: clock.RealClock{}, - idGenerator: util.NewULID, + queueService: queueService, + retryPolicyService: retryPolicyService, + publisher: publisher, + queueCache: queueCache, + submissionConfig: submissionConfig, + deduplicator: deduplicator, + authorizer: authorizer, + clock: clock.RealClock{}, + idGenerator: util.NewULID, } } @@ -464,3 +467,23 @@ func (s *Server) GetQueue(ctx context.Context, request *api.QueueGetRequest) (*a func (s *Server) GetQueues(request *api.StreamingQueueGetRequest, server api.Submit_GetQueuesServer) error { return s.queueService.GetQueues(request, server) } + +func (s *Server) CreateRetryPolicy(ctx context.Context, policy *api.RetryPolicy) (*types.Empty, error) { + return s.retryPolicyService.CreateRetryPolicy(ctx, policy) +} + +func (s *Server) UpdateRetryPolicy(ctx context.Context, policy *api.RetryPolicy) (*types.Empty, error) { + return s.retryPolicyService.UpdateRetryPolicy(ctx, policy) +} + +func (s *Server) DeleteRetryPolicy(ctx context.Context, req *api.RetryPolicyDeleteRequest) (*types.Empty, error) { + return s.retryPolicyService.DeleteRetryPolicy(ctx, req) +} + +func (s *Server) GetRetryPolicy(ctx context.Context, req *api.RetryPolicyGetRequest) (*api.RetryPolicy, error) { + return s.retryPolicyService.GetRetryPolicy(ctx, req) +} + +func (s *Server) GetRetryPolicies(ctx context.Context, req *api.RetryPolicyListRequest) (*api.RetryPolicyList, error) { + return s.retryPolicyService.GetRetryPolicies(ctx, req) +} diff --git a/internal/server/submit/submit_test.go b/internal/server/submit/submit_test.go index 17d3df49524..e66eb96d55d 100644 --- a/internal/server/submit/submit_test.go +++ b/internal/server/submit/submit_test.go @@ -528,6 +528,7 @@ func withTerminationGracePeriod(req *api.JobSubmitRequest, v *int64) *api.JobSub func createTestServer(t *testing.T) (*Server, *mockObjects) { m := createMocks(t) server := NewServer( + nil, nil, m.publisher, m.queueRepo, diff --git a/pkg/api/api.swagger.go b/pkg/api/api.swagger.go index 9cda2ebda25..2502156005a 100644 --- a/pkg/api/api.swagger.go +++ b/pkg/api/api.swagger.go @@ -691,6 +691,148 @@ func SwaggerJsonTemplate() string { " }\n" + " }\n" + " },\n" + + " \"/v1/retry-policies\": {\n" + + " \"get\": {\n" + + " \"tags\": [\n" + + " \"Submit\"\n" + + " ],\n" + + " \"operationId\": \"GetRetryPolicies\",\n" + + " \"responses\": {\n" + + " \"200\": {\n" + + " \"description\": \"A successful response.\",\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/apiRetryPolicyList\"\n" + + " }\n" + + " },\n" + + " \"default\": {\n" + + " \"description\": \"An unexpected error response.\",\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/runtimeError\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"/v1/retry-policy\": {\n" + + " \"post\": {\n" + + " \"tags\": [\n" + + " \"Submit\"\n" + + " ],\n" + + " \"operationId\": \"CreateRetryPolicy\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"name\": \"body\",\n" + + " \"in\": \"body\",\n" + + " \"required\": true,\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/apiRetryPolicy\"\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"responses\": {\n" + + " \"200\": {\n" + + " \"description\": \"A successful response.\",\n" + + " \"schema\": {}\n" + + " },\n" + + " \"default\": {\n" + + " \"description\": \"An unexpected error response.\",\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/runtimeError\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"/v1/retry-policy/{name}\": {\n" + + " \"get\": {\n" + + " \"tags\": [\n" + + " \"Submit\"\n" + + " ],\n" + + " \"operationId\": \"GetRetryPolicy\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"type\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"in\": \"path\",\n" + + " \"required\": true\n" + + " }\n" + + " ],\n" + + " \"responses\": {\n" + + " \"200\": {\n" + + " \"description\": \"A successful response.\",\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/apiRetryPolicy\"\n" + + " }\n" + + " },\n" + + " \"default\": {\n" + + " \"description\": \"An unexpected error response.\",\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/runtimeError\"\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"put\": {\n" + + " \"tags\": [\n" + + " \"Submit\"\n" + + " ],\n" + + " \"operationId\": \"UpdateRetryPolicy\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"type\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"in\": \"path\",\n" + + " \"required\": true\n" + + " },\n" + + " {\n" + + " \"name\": \"body\",\n" + + " \"in\": \"body\",\n" + + " \"required\": true,\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/apiRetryPolicy\"\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"responses\": {\n" + + " \"200\": {\n" + + " \"description\": \"A successful response.\",\n" + + " \"schema\": {}\n" + + " },\n" + + " \"default\": {\n" + + " \"description\": \"An unexpected error response.\",\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/runtimeError\"\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"delete\": {\n" + + " \"tags\": [\n" + + " \"Submit\"\n" + + " ],\n" + + " \"operationId\": \"DeleteRetryPolicy\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"type\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"in\": \"path\",\n" + + " \"required\": true\n" + + " }\n" + + " ],\n" + + " \"responses\": {\n" + + " \"200\": {\n" + + " \"description\": \"A successful response.\",\n" + + " \"schema\": {}\n" + + " },\n" + + " \"default\": {\n" + + " \"description\": \"An unexpected error response.\",\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/definitions/runtimeError\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + " \"/v1/run/details\": {\n" + " \"post\": {\n" + " \"tags\": [\n" + @@ -902,6 +1044,15 @@ func SwaggerJsonTemplate() string { " }\n" + " }\n" + " },\n" + + " \"apiExitCodeOperator\": {\n" + + " \"type\": \"string\",\n" + + " \"default\": \"EXIT_CODE_OPERATOR_UNSPECIFIED\",\n" + + " \"enum\": [\n" + + " \"EXIT_CODE_OPERATOR_UNSPECIFIED\",\n" + + " \"EXIT_CODE_OPERATOR_IN\",\n" + + " \"EXIT_CODE_OPERATOR_NOT_IN\"\n" + + " ]\n" + + " },\n" + " \"apiGetActiveQueuesRequest\": {\n" + " \"type\": \"object\"\n" + " },\n" + @@ -1287,6 +1438,10 @@ func SwaggerJsonTemplate() string { " },\n" + " \"reason\": {\n" + " \"type\": \"string\"\n" + + " },\n" + + " \"retryable\": {\n" + + " \"description\": \"retryable indicates the scheduler emitted this failure for an\\nintermediate (non-terminal) run that will be retried. When true,\\na subsequent leased/succeeded/failed event for the same job is\\nexpected. Default false preserves the prior behavior where every\\nemitted JobFailedEvent was terminal.\",\n" + + " \"type\": \"boolean\"\n" + " }\n" + " }\n" + " },\n" + @@ -2214,6 +2369,9 @@ func SwaggerJsonTemplate() string { " \"$ref\": \"#/definitions/apiPriorityClassResourceLimits\"\n" + " }\n" + " },\n" + + " \"retryPolicy\": {\n" + + " \"type\": \"string\"\n" + + " },\n" + " \"userOwners\": {\n" + " \"type\": \"array\",\n" + " \"items\": {\n" + @@ -2256,6 +2414,91 @@ func SwaggerJsonTemplate() string { " }\n" + " }\n" + " },\n" + + " \"apiRetryAction\": {\n" + + " \"type\": \"string\",\n" + + " \"default\": \"RETRY_ACTION_UNSPECIFIED\",\n" + + " \"enum\": [\n" + + " \"RETRY_ACTION_UNSPECIFIED\",\n" + + " \"RETRY_ACTION_FAIL\",\n" + + " \"RETRY_ACTION_RETRY\"\n" + + " ]\n" + + " },\n" + + " \"apiRetryExitCodeMatcher\": {\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"operator\": {\n" + + " \"$ref\": \"#/definitions/apiExitCodeOperator\"\n" + + " },\n" + + " \"values\": {\n" + + " \"type\": \"array\",\n" + + " \"items\": {\n" + + " \"type\": \"integer\",\n" + + " \"format\": \"int32\"\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"apiRetryPolicy\": {\n" + + " \"description\": \"RetryPolicy defines rules that determine whether failed jobs should be retried.\\nOperators create policies and assign them to queues by name.\",\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"defaultAction\": {\n" + + " \"$ref\": \"#/definitions/apiRetryAction\"\n" + + " },\n" + + " \"name\": {\n" + + " \"type\": \"string\"\n" + + " },\n" + + " \"retryLimit\": {\n" + + " \"description\": \"retry_limit is the maximum number of retries after the initial failure.\\nretry_limit: 3 allows up to 3 retries (4 total attempts before terminal\\nfailure). 0 means unlimited, subject to the scheduler's global cap.\",\n" + + " \"type\": \"integer\",\n" + + " \"format\": \"int64\"\n" + + " },\n" + + " \"rules\": {\n" + + " \"type\": \"array\",\n" + + " \"items\": {\n" + + " \"$ref\": \"#/definitions/apiRetryRule\"\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"apiRetryPolicyList\": {\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"retryPolicies\": {\n" + + " \"type\": \"array\",\n" + + " \"items\": {\n" + + " \"$ref\": \"#/definitions/apiRetryPolicy\"\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"apiRetryRule\": {\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"action\": {\n" + + " \"$ref\": \"#/definitions/apiRetryAction\"\n" + + " },\n" + + " \"onCategory\": {\n" + + " \"description\": \"on_category matches against Error.failure_category. When set with on_subcategory,\\nboth must match. Mirrors the engine's Rule.OnCategory / Rule.OnSubcategory.\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " \"onConditions\": {\n" + + " \"type\": \"array\",\n" + + " \"items\": {\n" + + " \"type\": \"string\"\n" + + " }\n" + + " },\n" + + " \"onExitCodes\": {\n" + + " \"$ref\": \"#/definitions/apiRetryExitCodeMatcher\"\n" + + " },\n" + + " \"onSubcategory\": {\n" + + " \"type\": \"string\"\n" + + " },\n" + + " \"onTerminationMessagePattern\": {\n" + + " \"type\": \"string\"\n" + + " }\n" + + " }\n" + + " },\n" + " \"apiServiceConfig\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + diff --git a/pkg/api/api.swagger.json b/pkg/api/api.swagger.json index d47f797d833..c5553e8c894 100644 --- a/pkg/api/api.swagger.json +++ b/pkg/api/api.swagger.json @@ -680,6 +680,148 @@ } } }, + "/v1/retry-policies": { + "get": { + "tags": [ + "Submit" + ], + "operationId": "GetRetryPolicies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apiRetryPolicyList" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/v1/retry-policy": { + "post": { + "tags": [ + "Submit" + ], + "operationId": "CreateRetryPolicy", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/apiRetryPolicy" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": {} + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, + "/v1/retry-policy/{name}": { + "get": { + "tags": [ + "Submit" + ], + "operationId": "GetRetryPolicy", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apiRetryPolicy" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + }, + "put": { + "tags": [ + "Submit" + ], + "operationId": "UpdateRetryPolicy", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/apiRetryPolicy" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": {} + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + }, + "delete": { + "tags": [ + "Submit" + ], + "operationId": "DeleteRetryPolicy", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": {} + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + } + } + }, "/v1/run/details": { "post": { "tags": [ @@ -891,6 +1033,15 @@ } } }, + "apiExitCodeOperator": { + "type": "string", + "default": "EXIT_CODE_OPERATOR_UNSPECIFIED", + "enum": [ + "EXIT_CODE_OPERATOR_UNSPECIFIED", + "EXIT_CODE_OPERATOR_IN", + "EXIT_CODE_OPERATOR_NOT_IN" + ] + }, "apiGetActiveQueuesRequest": { "type": "object" }, @@ -1276,6 +1427,10 @@ }, "reason": { "type": "string" + }, + "retryable": { + "description": "retryable indicates the scheduler emitted this failure for an\nintermediate (non-terminal) run that will be retried. When true,\na subsequent leased/succeeded/failed event for the same job is\nexpected. Default false preserves the prior behavior where every\nemitted JobFailedEvent was terminal.", + "type": "boolean" } } }, @@ -2203,6 +2358,9 @@ "$ref": "#/definitions/apiPriorityClassResourceLimits" } }, + "retryPolicy": { + "type": "string" + }, "userOwners": { "type": "array", "items": { @@ -2245,6 +2403,91 @@ } } }, + "apiRetryAction": { + "type": "string", + "default": "RETRY_ACTION_UNSPECIFIED", + "enum": [ + "RETRY_ACTION_UNSPECIFIED", + "RETRY_ACTION_FAIL", + "RETRY_ACTION_RETRY" + ] + }, + "apiRetryExitCodeMatcher": { + "type": "object", + "properties": { + "operator": { + "$ref": "#/definitions/apiExitCodeOperator" + }, + "values": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + } + }, + "apiRetryPolicy": { + "description": "RetryPolicy defines rules that determine whether failed jobs should be retried.\nOperators create policies and assign them to queues by name.", + "type": "object", + "properties": { + "defaultAction": { + "$ref": "#/definitions/apiRetryAction" + }, + "name": { + "type": "string" + }, + "retryLimit": { + "description": "retry_limit is the maximum number of retries after the initial failure.\nretry_limit: 3 allows up to 3 retries (4 total attempts before terminal\nfailure). 0 means unlimited, subject to the scheduler's global cap.", + "type": "integer", + "format": "int64" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/apiRetryRule" + } + } + } + }, + "apiRetryPolicyList": { + "type": "object", + "properties": { + "retryPolicies": { + "type": "array", + "items": { + "$ref": "#/definitions/apiRetryPolicy" + } + } + } + }, + "apiRetryRule": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/apiRetryAction" + }, + "onCategory": { + "description": "on_category matches against Error.failure_category. When set with on_subcategory,\nboth must match. Mirrors the engine's Rule.OnCategory / Rule.OnSubcategory.", + "type": "string" + }, + "onConditions": { + "type": "array", + "items": { + "type": "string" + } + }, + "onExitCodes": { + "$ref": "#/definitions/apiRetryExitCodeMatcher" + }, + "onSubcategory": { + "type": "string" + }, + "onTerminationMessagePattern": { + "type": "string" + } + } + }, "apiServiceConfig": { "type": "object", "properties": { diff --git a/pkg/api/deserialize.go b/pkg/api/deserialize.go index 28582b18dd1..3ca0c227927 100644 --- a/pkg/api/deserialize.go +++ b/pkg/api/deserialize.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "fmt" + "strings" ) func (x *IngressType) UnmarshalJSON(data []byte) error { @@ -77,3 +78,72 @@ func (x *JobState) UnmarshalJSON(data []byte) error { *x = JobState(value) return nil } + +// UnmarshalJSON for RetryAction accepts the proto canonical name +// ("RETRY_ACTION_FAIL"), a numeric value, or a friendly alias ("Fail", "Retry"), +// so operator-authored YAML can use the natural short form rather than the +// prefixed proto enum name. +func (x *RetryAction) UnmarshalJSON(data []byte) error { + v, err := unmarshalProtoEnum(data, "RetryAction", "RETRY_ACTION_", RetryAction_value, RetryAction_name) + if err != nil { + return err + } + *x = RetryAction(v) + return nil +} + +// UnmarshalJSON for ExitCodeOperator accepts the proto canonical name +// ("EXIT_CODE_OPERATOR_IN"), a numeric value, or a friendly alias ("In", "NotIn"). +func (x *ExitCodeOperator) UnmarshalJSON(data []byte) error { + v, err := unmarshalProtoEnum(data, "ExitCodeOperator", "EXIT_CODE_OPERATOR_", ExitCodeOperator_value, ExitCodeOperator_name) + if err != nil { + return err + } + *x = ExitCodeOperator(v) + return nil +} + +// unmarshalProtoEnum decodes a proto3 enum from JSON, accepting: +// - a numeric value (e.g. 1) +// - the canonical proto name (e.g. "RETRY_ACTION_FAIL") +// - a friendly alias derived from the canonical name with prefix stripped +// and case/underscores ignored (e.g. "Fail", "fail", "NotIn", "not_in"). +// +// typeName is used only for error messages. canonicalPrefix identifies the +// portion of every canonical name to strip when matching friendly aliases +// (e.g. "RETRY_ACTION_"). +func unmarshalProtoEnum( + data []byte, + typeName, canonicalPrefix string, + byName map[string]int32, + byValue map[int32]string, +) (int32, error) { + var n int32 + if err := json.Unmarshal(data, &n); err == nil { + if _, ok := byValue[n]; !ok { + return 0, fmt.Errorf("no %s of value %d", typeName, n) + } + return n, nil + } + var s string + if err := json.Unmarshal(data, &s); err != nil { + return 0, err + } + if v, ok := byName[s]; ok { + return v, nil + } + want := normalizeAlias(s) + for canonical, v := range byName { + if normalizeAlias(strings.TrimPrefix(canonical, canonicalPrefix)) == want { + return v, nil + } + } + return 0, fmt.Errorf("no %s of name %q", typeName, s) +} + +// normalizeAlias collapses an enum-name candidate to a comparable form by +// stripping underscores and lower-casing, so "NotIn"/"NOT_IN"/"not_in" all +// canonicalise to "notin". +func normalizeAlias(s string) string { + return strings.ToLower(strings.ReplaceAll(s, "_", "")) +} diff --git a/pkg/api/deserialize_test.go b/pkg/api/deserialize_test.go index 9c73e38f83f..97fba0ce502 100644 --- a/pkg/api/deserialize_test.go +++ b/pkg/api/deserialize_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestMarshalJsonIngressType(t *testing.T) { @@ -133,3 +134,61 @@ func deserializeJobState(input []byte) error { return deserializer.x.UnmarshalJSON(input) } + +func TestUnmarshalRetryAction_AcceptsCanonicalAliasAndNumeric(t *testing.T) { + tests := map[string]struct { + input string + expected RetryAction + }{ + "canonical FAIL": {`"RETRY_ACTION_FAIL"`, RetryAction_RETRY_ACTION_FAIL}, + "canonical RETRY": {`"RETRY_ACTION_RETRY"`, RetryAction_RETRY_ACTION_RETRY}, + "alias Fail": {`"Fail"`, RetryAction_RETRY_ACTION_FAIL}, + "alias Retry": {`"Retry"`, RetryAction_RETRY_ACTION_RETRY}, + "alias FAIL": {`"FAIL"`, RetryAction_RETRY_ACTION_FAIL}, + "alias retry": {`"retry"`, RetryAction_RETRY_ACTION_RETRY}, + "numeric 1": {`1`, RetryAction_RETRY_ACTION_FAIL}, + "numeric 2": {`2`, RetryAction_RETRY_ACTION_RETRY}, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + var got RetryAction + require.NoError(t, got.UnmarshalJSON([]byte(tc.input))) + assert.Equal(t, tc.expected, got) + }) + } +} + +func TestUnmarshalRetryAction_RejectsInvalid(t *testing.T) { + tests := map[string]string{ + "unknown name": `"BANANAS"`, + "out-of-range number": `99`, + "non-string non-int": `{}`, + } + for name, input := range tests { + t.Run(name, func(t *testing.T) { + var got RetryAction + assert.Error(t, got.UnmarshalJSON([]byte(input))) + }) + } +} + +func TestUnmarshalExitCodeOperator_AcceptsCanonicalAliasAndNumeric(t *testing.T) { + tests := map[string]struct { + input string + expected ExitCodeOperator + }{ + "canonical IN": {`"EXIT_CODE_OPERATOR_IN"`, ExitCodeOperator_EXIT_CODE_OPERATOR_IN}, + "canonical NOT_IN": {`"EXIT_CODE_OPERATOR_NOT_IN"`, ExitCodeOperator_EXIT_CODE_OPERATOR_NOT_IN}, + "alias In": {`"In"`, ExitCodeOperator_EXIT_CODE_OPERATOR_IN}, + "alias NotIn": {`"NotIn"`, ExitCodeOperator_EXIT_CODE_OPERATOR_NOT_IN}, + "alias notin": {`"notin"`, ExitCodeOperator_EXIT_CODE_OPERATOR_NOT_IN}, + "numeric 1": {`1`, ExitCodeOperator_EXIT_CODE_OPERATOR_IN}, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + var got ExitCodeOperator + require.NoError(t, got.UnmarshalJSON([]byte(tc.input))) + assert.Equal(t, tc.expected, got) + }) + } +} diff --git a/pkg/api/event.pb.go b/pkg/api/event.pb.go index 284dc453a0e..32a703ad184 100644 --- a/pkg/api/event.pb.go +++ b/pkg/api/event.pb.go @@ -850,6 +850,12 @@ type JobFailedEvent struct { Cause Cause `protobuf:"varint,12,opt,name=cause,proto3,enum=api.Cause" json:"cause,omitempty"` FailureCategory string `protobuf:"bytes,16,opt,name=failure_category,json=failureCategory,proto3" json:"failureCategory,omitempty"` FailureSubcategory string `protobuf:"bytes,17,opt,name=failure_subcategory,json=failureSubcategory,proto3" json:"failureSubcategory,omitempty"` + // retryable indicates the scheduler emitted this failure for an + // intermediate (non-terminal) run that will be retried. When true, + // a subsequent leased/succeeded/failed event for the same job is + // expected. Default false preserves the prior behavior where every + // emitted JobFailedEvent was terminal. + Retryable bool `protobuf:"varint,18,opt,name=retryable,proto3" json:"retryable,omitempty"` } func (m *JobFailedEvent) Reset() { *m = JobFailedEvent{} } @@ -998,6 +1004,13 @@ func (m *JobFailedEvent) GetFailureSubcategory() string { return "" } +func (m *JobFailedEvent) GetRetryable() bool { + if m != nil { + return m.Retryable + } + return false +} + type JobPreemptingEvent struct { JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"` JobSetId string `protobuf:"bytes,2,opt,name=job_set_id,json=jobSetId,proto3" json:"jobSetId,omitempty"` @@ -2479,156 +2492,157 @@ func init() { func init() { proto.RegisterFile("pkg/api/event.proto", fileDescriptor_7758595c3bb8cf56) } var fileDescriptor_7758595c3bb8cf56 = []byte{ - // 2373 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0x4d, 0x6c, 0x1b, 0xc7, - 0xf5, 0xf7, 0x52, 0xfc, 0x58, 0x0e, 0x25, 0x91, 0x1a, 0x7d, 0x98, 0xa6, 0x1d, 0x51, 0xa0, 0x81, - 0xfc, 0x15, 0x23, 0x26, 0xf3, 0x97, 0x93, 0x22, 0x30, 0x0a, 0x14, 0x96, 0xa2, 0xc4, 0x62, 0xe3, - 0xda, 0xa6, 0x1c, 0x24, 0x2d, 0x02, 0xb0, 0xcb, 0xdd, 0x11, 0xb5, 0x12, 0xb9, 0xb3, 0xd9, 0x0f, - 0xd9, 0x8a, 0x91, 0x4b, 0x7b, 0xe9, 0xa1, 0x28, 0xfa, 0x81, 0xde, 0x8a, 0xb6, 0xe7, 0x1e, 0x7b, - 0xe9, 0xad, 0xe8, 0xa9, 0x28, 0x7a, 0x0a, 0x9a, 0x4b, 0x4f, 0x44, 0x6b, 0x17, 0x29, 0x40, 0xf4, - 0xd0, 0x4b, 0xef, 0xc5, 0xbc, 0x99, 0x5d, 0xce, 0xac, 0x28, 0x48, 0x56, 0x3e, 0x6a, 0x28, 0x3c, - 0xd9, 0xfa, 0xbd, 0x79, 0x6f, 0xde, 0xbc, 0xf9, 0xcd, 0xcc, 0x9b, 0x7d, 0x43, 0x34, 0xef, 0xee, - 0x77, 0x1b, 0x86, 0x6b, 0x37, 0xc8, 0x01, 0x71, 0x82, 0xba, 0xeb, 0xd1, 0x80, 0xe2, 0x29, 0xc3, - 0xb5, 0x2b, 0xd5, 0x2e, 0xa5, 0xdd, 0x1e, 0x69, 0x00, 0xd4, 0x09, 0x77, 0x1a, 0x81, 0xdd, 0x27, - 0x7e, 0x60, 0xf4, 0x5d, 0xde, 0xaa, 0xb2, 0x10, 0xa9, 0xfa, 0x61, 0xa7, 0x6f, 0x07, 0x49, 0x74, - 0x97, 0x18, 0xbd, 0x60, 0x57, 0xa0, 0x97, 0x93, 0xc6, 0x48, 0xdf, 0x0d, 0x0e, 0x85, 0xf0, 0x8a, - 0x10, 0x32, 0x2d, 0xc3, 0x71, 0x68, 0x60, 0x04, 0x36, 0x75, 0x7c, 0x21, 0x7d, 0x75, 0xff, 0x75, - 0xbf, 0x6e, 0x53, 0x26, 0xed, 0x1b, 0xe6, 0xae, 0xed, 0x10, 0xef, 0xb0, 0x11, 0x75, 0xe2, 0x11, - 0x9f, 0x86, 0x9e, 0x49, 0x1a, 0x5d, 0xe2, 0x10, 0xcf, 0x08, 0x88, 0xc5, 0xb5, 0x6a, 0xbf, 0x48, - 0xa1, 0xb9, 0x26, 0xed, 0x6c, 0x83, 0x6b, 0x01, 0xb1, 0x36, 0xd9, 0xf0, 0xf0, 0x35, 0x94, 0xdd, - 0xa3, 0x9d, 0xb6, 0x6d, 0x95, 0xb5, 0x15, 0x6d, 0x35, 0xbf, 0x3e, 0x3f, 0x1c, 0x54, 0x8b, 0x7b, - 0xb4, 0xb3, 0x65, 0xbd, 0x4c, 0xfb, 0x76, 0x00, 0x4e, 0xb5, 0x32, 0x00, 0xe0, 0x57, 0x11, 0x62, - 0x6d, 0x7d, 0x12, 0xb0, 0xf6, 0x29, 0x68, 0xbf, 0x34, 0x1c, 0x54, 0xf1, 0x1e, 0xed, 0x6c, 0x93, - 0x40, 0x51, 0xd1, 0x23, 0x0c, 0xbf, 0x84, 0x32, 0x1f, 0x84, 0x24, 0x24, 0xe5, 0xa9, 0x51, 0x07, - 0x00, 0xc8, 0x1d, 0x00, 0x80, 0xbf, 0x89, 0x72, 0xa6, 0x47, 0x98, 0xcf, 0xe5, 0xf4, 0x8a, 0xb6, - 0x5a, 0x58, 0xab, 0xd4, 0x79, 0x20, 0xea, 0x51, 0x94, 0xea, 0x0f, 0xa2, 0x90, 0xaf, 0x2f, 0x0e, - 0x07, 0xd5, 0x39, 0xd1, 0x5c, 0x32, 0x15, 0x59, 0xc0, 0xd7, 0xd1, 0xd4, 0x1e, 0xed, 0x94, 0x33, - 0x60, 0x48, 0xaf, 0x1b, 0xae, 0x5d, 0x6f, 0xd2, 0xce, 0xfa, 0xdc, 0x70, 0x50, 0x9d, 0xd9, 0xa3, - 0x1d, 0x49, 0x85, 0xb5, 0xab, 0x0d, 0x35, 0x34, 0xdb, 0xa4, 0x9d, 0xfb, 0xcc, 0x91, 0xf3, 0x1e, - 0x9b, 0xda, 0x9f, 0x53, 0x30, 0xd8, 0xb7, 0x89, 0xe1, 0x9f, 0x7f, 0x22, 0x7c, 0x0d, 0x21, 0xb3, - 0x17, 0xfa, 0x01, 0xf1, 0x98, 0xb7, 0x19, 0xe8, 0xfc, 0xe2, 0x70, 0x50, 0x9d, 0x17, 0xa8, 0xe2, - 0x6e, 0x3e, 0x06, 0xf1, 0x8b, 0x28, 0xed, 0x52, 0xda, 0x2b, 0x67, 0x41, 0x03, 0x0f, 0x07, 0xd5, - 0x59, 0xf6, 0xb7, 0xd4, 0x18, 0xe4, 0xb5, 0x9f, 0xa4, 0xd1, 0x62, 0x14, 0xcc, 0x16, 0x09, 0x42, - 0xcf, 0x99, 0xc4, 0xf4, 0xb8, 0x98, 0xbe, 0x8c, 0xb2, 0x1e, 0x31, 0x7c, 0xea, 0x88, 0xa8, 0x2e, - 0x0c, 0x07, 0xd5, 0x12, 0x47, 0x24, 0x05, 0xd1, 0x06, 0x7f, 0x03, 0xcd, 0xec, 0x87, 0x1d, 0xe2, - 0x39, 0x24, 0x20, 0x3e, 0xeb, 0x28, 0x07, 0x4a, 0x95, 0xe1, 0xa0, 0xba, 0x34, 0x12, 0x28, 0x7d, - 0x4d, 0xcb, 0x38, 0x73, 0xd3, 0xa5, 0x56, 0xdb, 0x09, 0xfb, 0x1d, 0xe2, 0x95, 0xf5, 0x15, 0x6d, - 0x35, 0xc3, 0xdd, 0x74, 0xa9, 0xf5, 0x2d, 0x00, 0x65, 0x37, 0x63, 0x90, 0x75, 0xec, 0x85, 0x4e, - 0xdb, 0x08, 0x40, 0x44, 0xac, 0x72, 0x7e, 0x45, 0x5b, 0xd5, 0x79, 0xc7, 0x5e, 0xe8, 0xdc, 0x8a, - 0x70, 0xb9, 0x63, 0x19, 0xaf, 0xfd, 0x5b, 0x43, 0x0b, 0x11, 0x27, 0x36, 0x1f, 0xb9, 0xb6, 0x77, - 0xfe, 0xf7, 0x94, 0xdf, 0xa5, 0x51, 0xb1, 0x49, 0x3b, 0xf7, 0x88, 0x63, 0xd9, 0x4e, 0x77, 0xb2, - 0x00, 0xc6, 0x2f, 0x80, 0x23, 0x94, 0xce, 0x7e, 0x26, 0x4a, 0xe7, 0x4e, 0x4d, 0xe9, 0x57, 0x90, - 0x0e, 0x7a, 0x46, 0x9f, 0xc0, 0x42, 0xc8, 0xf3, 0x21, 0xb2, 0x06, 0x46, 0x5f, 0x8e, 0x56, 0x4e, - 0x40, 0xcc, 0xd5, 0x48, 0xc3, 0x77, 0x0d, 0x93, 0xc0, 0x22, 0x10, 0xae, 0x8a, 0x36, 0x80, 0xcb, - 0xae, 0xca, 0x78, 0xbc, 0x81, 0xa2, 0x13, 0x36, 0xd0, 0x7f, 0x71, 0xe6, 0xb4, 0x42, 0xc7, 0x99, - 0x30, 0xe7, 0x8b, 0x63, 0xce, 0x0d, 0x94, 0x77, 0xa8, 0x45, 0x38, 0x05, 0x72, 0xa3, 0x28, 0x31, - 0x30, 0xc1, 0x01, 0x3d, 0xc2, 0xce, 0xbc, 0x83, 0xca, 0x74, 0xcb, 0x9f, 0x8d, 0x6e, 0xe8, 0x8c, - 0x74, 0x2b, 0x9c, 0x40, 0xb7, 0xdf, 0x66, 0xd1, 0x7c, 0x93, 0x76, 0xb6, 0x9c, 0xae, 0x47, 0x7c, - 0x7f, 0xcb, 0xd9, 0xa1, 0x13, 0xca, 0x9d, 0x37, 0xca, 0xa1, 0xb3, 0x51, 0xae, 0xf0, 0x8c, 0x94, - 0x7b, 0x8c, 0xe6, 0x6c, 0x4e, 0xa3, 0xb6, 0x61, 0x59, 0xec, 0x5f, 0xe2, 0x97, 0xf3, 0x2b, 0x53, - 0xab, 0x85, 0xb5, 0x7a, 0x74, 0xe3, 0x48, 0xf2, 0xac, 0x2e, 0x80, 0x5b, 0x91, 0xc2, 0xa6, 0x13, - 0x78, 0x87, 0xeb, 0xcb, 0xc3, 0x41, 0xb5, 0x62, 0x27, 0x44, 0x52, 0xc7, 0xa5, 0xa4, 0xac, 0xb2, - 0x8f, 0x16, 0xc7, 0x9a, 0xc2, 0x57, 0xd1, 0xd4, 0x3e, 0x39, 0x04, 0x16, 0x67, 0xf8, 0x7d, 0x67, - 0x9f, 0x1c, 0xca, 0xf7, 0x9d, 0x7d, 0x72, 0xc8, 0xb8, 0x78, 0x60, 0xf4, 0x42, 0x22, 0xc8, 0x0b, - 0x5c, 0x04, 0x40, 0xe6, 0x22, 0x00, 0x37, 0x53, 0xaf, 0x6b, 0xb5, 0xff, 0xe8, 0x70, 0x63, 0x78, - 0xd3, 0xb0, 0x7b, 0x93, 0xec, 0xf6, 0xf3, 0xc9, 0x6e, 0xdf, 0x47, 0x88, 0x3c, 0xb2, 0x83, 0xb6, - 0x49, 0x2d, 0xe2, 0x97, 0x73, 0xc0, 0x9a, 0x5a, 0xc4, 0x1a, 0x29, 0xd0, 0xf5, 0xcd, 0x47, 0x76, - 0xb0, 0xc1, 0x1a, 0x71, 0xa6, 0x5c, 0x62, 0x9e, 0x90, 0x08, 0x1b, 0x19, 0x2e, 0x6b, 0xad, 0x7c, - 0x0c, 0x1f, 0x5d, 0xbb, 0xfa, 0x67, 0x59, 0xbb, 0xf9, 0x33, 0xad, 0x5d, 0x74, 0xa6, 0xb5, 0x3b, - 0x73, 0xb6, 0xb5, 0x3b, 0xfb, 0x8c, 0x6b, 0xd7, 0x42, 0xd8, 0xa4, 0x4e, 0x60, 0xd8, 0x0e, 0xf1, - 0xda, 0x7e, 0x60, 0x04, 0x21, 0x5b, 0xbc, 0x05, 0x98, 0x86, 0x05, 0x98, 0x86, 0x8d, 0x48, 0xbc, - 0x0d, 0xd2, 0xf5, 0xea, 0x70, 0x50, 0xbd, 0x6c, 0xaa, 0xa0, 0xb2, 0x46, 0xe7, 0x8e, 0x08, 0xf1, - 0x6b, 0x28, 0x63, 0x1a, 0xa1, 0x4f, 0xca, 0xd3, 0x2b, 0xda, 0xea, 0xec, 0x1a, 0xe2, 0x86, 0x19, - 0xc2, 0xe9, 0x0c, 0x42, 0x99, 0xce, 0x00, 0xe0, 0xdb, 0xa8, 0xb4, 0x63, 0xd8, 0xbd, 0xd0, 0x23, - 0x6d, 0xd3, 0x08, 0x48, 0x97, 0x7a, 0x87, 0xe5, 0x12, 0x0c, 0xf0, 0x85, 0xe1, 0xa0, 0x7a, 0x49, - 0xc8, 0x36, 0x84, 0x48, 0xd2, 0x2f, 0x26, 0x44, 0xf8, 0x3e, 0x9a, 0x8f, 0x2c, 0xf9, 0x61, 0x27, - 0x36, 0x36, 0x07, 0xc6, 0x56, 0x86, 0x83, 0xea, 0x15, 0x21, 0xde, 0x1e, 0x49, 0x25, 0x7b, 0xf8, - 0xa8, 0xb4, 0x62, 0xa1, 0x59, 0x95, 0x92, 0xf2, 0x8e, 0x93, 0x3f, 0xdd, 0x8e, 0x93, 0x39, 0x69, - 0xc7, 0x69, 0xa6, 0xf5, 0x62, 0xa9, 0x54, 0xfb, 0x24, 0x85, 0x30, 0xbb, 0x55, 0x78, 0x84, 0x35, - 0xf8, 0x0a, 0xa4, 0x87, 0xaf, 0xa1, 0xbc, 0x47, 0x3e, 0x08, 0x89, 0x1f, 0x50, 0x4f, 0xde, 0x7a, - 0x62, 0x50, 0x5e, 0x40, 0x31, 0xf8, 0x6c, 0x5b, 0x4f, 0xed, 0xe7, 0x69, 0xf8, 0x16, 0x28, 0xa2, - 0x3a, 0xd9, 0xd0, 0x8f, 0xdb, 0xd0, 0xaf, 0xa1, 0xac, 0x17, 0x3a, 0xa3, 0xcc, 0x07, 0x1c, 0xf6, - 0x42, 0x47, 0x8d, 0x08, 0x00, 0x78, 0x0b, 0xcd, 0xb9, 0x82, 0xa5, 0x07, 0xa4, 0x2d, 0x02, 0x99, - 0x1b, 0xad, 0xd9, 0x91, 0xb0, 0x99, 0x08, 0x69, 0x31, 0x21, 0x4a, 0x98, 0x12, 0x1e, 0xe8, 0xe3, - 0x4c, 0xb5, 0x12, 0xbe, 0x14, 0x13, 0x22, 0x89, 0x17, 0xf9, 0x53, 0xf0, 0xe2, 0x8f, 0x69, 0xf1, - 0x8d, 0xd8, 0x34, 0x09, 0xb1, 0x26, 0xbc, 0x98, 0xdc, 0xc5, 0xce, 0x76, 0x17, 0xab, 0xfd, 0xbd, - 0x00, 0x77, 0xac, 0x77, 0x02, 0xbb, 0x67, 0xfb, 0x50, 0xbc, 0x98, 0x50, 0xe9, 0x0b, 0xa2, 0xd2, - 0x8f, 0x34, 0xb4, 0x78, 0xc7, 0x78, 0xd4, 0x12, 0x75, 0x1f, 0xff, 0x4d, 0xea, 0xdd, 0x23, 0x9e, - 0x4d, 0x2d, 0x91, 0x52, 0xde, 0x88, 0x52, 0xca, 0xe4, 0x64, 0xd4, 0xc7, 0x6a, 0xf1, 0x1c, 0xf3, - 0xea, 0x70, 0x50, 0xad, 0x8e, 0x95, 0x4b, 0x7e, 0x8c, 0xef, 0x56, 0xe5, 0xb6, 0x7e, 0x26, 0x6e, - 0xe7, 0x9f, 0xe7, 0x4b, 0xdf, 0x0f, 0x35, 0xb4, 0x14, 0xd0, 0xc0, 0xe8, 0xb5, 0xcd, 0xb0, 0x1f, - 0xf6, 0x0c, 0xd8, 0xa4, 0x43, 0xdf, 0xe8, 0xb2, 0x24, 0x8f, 0x45, 0x7c, 0xed, 0xd8, 0x88, 0x3f, - 0x60, 0x6a, 0x1b, 0xb1, 0xd6, 0x3b, 0x4c, 0x89, 0x07, 0xbc, 0x36, 0x1c, 0x54, 0x97, 0x83, 0x31, - 0x62, 0xc9, 0x8d, 0x85, 0x71, 0x72, 0x98, 0xff, 0x5b, 0x07, 0xdd, 0x31, 0xf3, 0x3f, 0x73, 0xc2, - 0xfc, 0x8f, 0xd5, 0x92, 0xe6, 0x7f, 0xac, 0x5c, 0x9e, 0xff, 0xb1, 0x0d, 0x2a, 0xbf, 0xd6, 0x50, - 0xe5, 0x78, 0x6a, 0x9d, 0x2e, 0x57, 0xfc, 0xb6, 0x9c, 0x2b, 0xb2, 0xcb, 0x34, 0x2f, 0x79, 0xd6, - 0xe5, 0x92, 0x67, 0xdd, 0xdd, 0xef, 0xc2, 0xd8, 0xa2, 0x92, 0x67, 0xfd, 0x7e, 0x68, 0x38, 0x81, - 0x1d, 0x1c, 0x9e, 0x94, 0x5b, 0x56, 0x7e, 0xa5, 0xa1, 0x4b, 0xc7, 0xce, 0xc5, 0x73, 0xe1, 0x21, - 0x0b, 0xe2, 0xf1, 0xf3, 0xf3, 0x3c, 0xb8, 0x58, 0xfb, 0x67, 0x0a, 0x2d, 0x35, 0x69, 0xa7, 0x45, - 0x5c, 0xcf, 0xa6, 0x9e, 0x1d, 0xd8, 0x1f, 0x7e, 0x05, 0xd2, 0xf3, 0xaf, 0xa3, 0x69, 0x87, 0x3c, - 0x6c, 0x8b, 0x21, 0x1f, 0xc2, 0x46, 0xaf, 0xc1, 0x95, 0x7c, 0xd1, 0x21, 0x0f, 0xef, 0x09, 0x58, - 0xd2, 0x2c, 0x48, 0xb0, 0x9a, 0xdc, 0x67, 0x4f, 0x9b, 0xdc, 0xd7, 0x3e, 0x4d, 0x41, 0x85, 0x51, - 0x8a, 0xf4, 0xf9, 0x4f, 0xcd, 0xfe, 0x27, 0x81, 0x16, 0xb7, 0xcd, 0x0d, 0xc3, 0x31, 0x49, 0xaf, - 0x37, 0xb9, 0x6d, 0x7e, 0x3e, 0xb7, 0xcd, 0xbf, 0xf0, 0x97, 0x27, 0x22, 0xaa, 0xe7, 0x9f, 0xba, - 0x5f, 0x4a, 0x50, 0xff, 0x90, 0x06, 0xaa, 0x3e, 0x20, 0x5e, 0xdf, 0x76, 0x8c, 0xc9, 0x1d, 0xfe, - 0xf9, 0xae, 0xb8, 0x7e, 0x49, 0x25, 0xb0, 0x11, 0x85, 0xf4, 0x53, 0x50, 0xe8, 0xf7, 0x05, 0x34, - 0x0d, 0xac, 0xb9, 0x43, 0x7c, 0x48, 0x25, 0xef, 0xa2, 0xbc, 0x1f, 0x3d, 0x0f, 0x03, 0xfe, 0x14, - 0xd6, 0x96, 0xa2, 0xec, 0x51, 0x7d, 0x37, 0xc6, 0x03, 0x10, 0x37, 0x1e, 0x19, 0xbf, 0x7d, 0xa1, - 0x35, 0xb2, 0x81, 0x37, 0x50, 0x16, 0x98, 0x60, 0x89, 0x14, 0x64, 0x3e, 0xb2, 0x26, 0x3d, 0xb3, - 0xe2, 0x4e, 0xf2, 0x66, 0x8a, 0x1d, 0xa1, 0xca, 0x8c, 0xf4, 0xe0, 0xa1, 0x12, 0x30, 0x4e, 0x32, - 0x22, 0x3d, 0x5f, 0xe2, 0x46, 0x78, 0x33, 0xd5, 0x08, 0xc7, 0xf0, 0x77, 0xd1, 0x2c, 0xfc, 0xaf, - 0xed, 0x89, 0x17, 0x3a, 0x31, 0x23, 0x65, 0x63, 0xca, 0xf3, 0x9d, 0xf5, 0xcb, 0xc3, 0x41, 0xf5, - 0x62, 0x4f, 0xc6, 0x15, 0xd3, 0x33, 0x8a, 0x08, 0xbf, 0x8f, 0x38, 0xd0, 0x26, 0xfc, 0xbd, 0x87, - 0x78, 0x79, 0x76, 0x49, 0xe9, 0x40, 0x7e, 0x0b, 0xc2, 0xe7, 0xb5, 0x27, 0xc1, 0x8a, 0xf9, 0x69, - 0x59, 0x82, 0xdf, 0x42, 0x39, 0x97, 0xbf, 0xac, 0x00, 0xfe, 0x46, 0x9f, 0xa8, 0x13, 0x0f, 0x2e, - 0x04, 0xc3, 0x38, 0xa2, 0x58, 0x8b, 0xb4, 0x99, 0x21, 0x8f, 0x17, 0xda, 0x81, 0xca, 0x92, 0x21, - 0xb9, 0xfe, 0xce, 0x0d, 0x89, 0x86, 0xaa, 0x21, 0x01, 0xb2, 0x69, 0xd9, 0x81, 0x22, 0x05, 0x90, - 0x5b, 0x9a, 0x16, 0xa9, 0x74, 0xc1, 0xa7, 0x85, 0x37, 0x53, 0xa7, 0x85, 0x63, 0x9c, 0x71, 0xe2, - 0x63, 0x13, 0xb0, 0x5d, 0x61, 0x9c, 0xfc, 0x15, 0x2a, 0x62, 0x9c, 0xc0, 0x92, 0x8c, 0x13, 0x30, - 0x6e, 0xa3, 0x19, 0x4f, 0x4e, 0x93, 0xe0, 0x76, 0x27, 0x4d, 0xf3, 0xd1, 0x1c, 0x8a, 0x4f, 0xb3, - 0xa2, 0xa4, 0x4e, 0xb3, 0x22, 0xc2, 0xdb, 0x08, 0x99, 0x71, 0x7a, 0x00, 0x5f, 0xf5, 0x0b, 0x6b, - 0x17, 0x23, 0xeb, 0x89, 0xc4, 0x61, 0xbd, 0x3c, 0x1c, 0x54, 0x17, 0x46, 0xcd, 0x15, 0xbb, 0x92, - 0x19, 0x16, 0x06, 0x33, 0x3a, 0x1d, 0xa1, 0xfe, 0x21, 0x85, 0x41, 0x3d, 0x36, 0xc5, 0x96, 0x17, - 0x61, 0x6a, 0x18, 0x62, 0x18, 0xbf, 0x8b, 0x0a, 0xe1, 0xe8, 0xba, 0x57, 0x2e, 0x82, 0xc9, 0xf2, - 0x71, 0x37, 0x41, 0x9e, 0x56, 0x49, 0x0a, 0x8a, 0x59, 0xd9, 0x12, 0x7e, 0x0f, 0x4d, 0x47, 0x15, - 0x4f, 0xdb, 0xd9, 0xa1, 0x50, 0x47, 0x90, 0x2c, 0x27, 0x8b, 0x9d, 0xdc, 0xb2, 0x3d, 0x42, 0x55, - 0xcb, 0x92, 0x00, 0x9b, 0x68, 0xd6, 0x53, 0xae, 0x12, 0x65, 0x0c, 0xb6, 0x2f, 0x8f, 0x99, 0xba, - 0x38, 0xc0, 0x57, 0x86, 0x83, 0x6a, 0x59, 0x55, 0x53, 0x7a, 0x48, 0x98, 0x64, 0x81, 0x76, 0xa3, - 0x8f, 0xde, 0xe5, 0x45, 0x35, 0xd0, 0xea, 0xd7, 0x70, 0xb1, 0xc5, 0x47, 0x98, 0x1a, 0xe8, 0x18, - 0x66, 0x74, 0x70, 0xe3, 0xda, 0x44, 0x79, 0x49, 0xa5, 0x43, 0xa2, 0x6a, 0xc1, 0xe9, 0x30, 0x6a, - 0xae, 0xd2, 0x61, 0x84, 0xaf, 0xeb, 0x28, 0x0b, 0x8f, 0x8f, 0xfd, 0x66, 0x5a, 0xd7, 0x4b, 0xf9, - 0x66, 0x5a, 0x9f, 0x2d, 0x15, 0x9b, 0x69, 0xbd, 0x54, 0x9a, 0x6b, 0xa6, 0xf5, 0xf9, 0xd2, 0x42, - 0x33, 0xad, 0x2f, 0x94, 0x16, 0x6b, 0xdf, 0x4f, 0xa1, 0x62, 0xa2, 0x48, 0x85, 0x5f, 0x44, 0x69, - 0x38, 0x71, 0xb4, 0xd1, 0x2b, 0x08, 0x47, 0x3d, 0x6e, 0x40, 0x8e, 0xd7, 0x90, 0x1e, 0x15, 0x0b, - 0x45, 0x41, 0x06, 0x8e, 0xfe, 0x08, 0x93, 0x8f, 0xfe, 0x08, 0xc3, 0x0d, 0x94, 0xeb, 0xf3, 0xa3, - 0x42, 0x1c, 0xfe, 0xb0, 0x4b, 0x08, 0x48, 0x3e, 0xd0, 0x04, 0x24, 0x9d, 0x47, 0xe9, 0x53, 0x14, - 0x44, 0xe3, 0x5a, 0x59, 0xe6, 0x59, 0x6a, 0x65, 0xb5, 0x0f, 0x11, 0x86, 0xf0, 0x6e, 0x07, 0x1e, - 0x31, 0xfa, 0xd1, 0x59, 0xb6, 0x82, 0x52, 0x71, 0x12, 0x54, 0x1a, 0x0e, 0xaa, 0xd3, 0xb6, 0x7c, - 0xc2, 0xa7, 0x6c, 0x0b, 0xaf, 0x8f, 0x46, 0xc3, 0x4f, 0xa7, 0x39, 0xe8, 0x50, 0x3e, 0x11, 0x4f, - 0x1a, 0x60, 0xed, 0xa7, 0x29, 0x34, 0xd3, 0x84, 0xcc, 0xa8, 0xc5, 0xf3, 0xb8, 0x53, 0xf4, 0xfb, - 0x12, 0xca, 0x3c, 0x34, 0x02, 0x73, 0x17, 0x7a, 0xd5, 0xf9, 0xd0, 0x00, 0x90, 0x87, 0x06, 0x00, - 0xde, 0x40, 0xc5, 0x1d, 0x8f, 0xf6, 0xdb, 0xa2, 0x3b, 0x96, 0xbd, 0xf0, 0xc0, 0xc3, 0x9e, 0xc5, - 0x44, 0xc2, 0x51, 0x25, 0x7d, 0x99, 0x51, 0x04, 0xa3, 0x84, 0x2d, 0x7d, 0x62, 0xc2, 0xf6, 0x06, - 0x9a, 0x25, 0x9e, 0x47, 0xbd, 0xad, 0x9d, 0x3b, 0xb6, 0xef, 0x33, 0x46, 0x67, 0xc0, 0x47, 0x58, - 0x66, 0xaa, 0x44, 0x52, 0x4e, 0xe8, 0xd4, 0x7e, 0xa9, 0xa1, 0xe9, 0x77, 0x99, 0xff, 0x51, 0x4c, - 0x62, 0x0f, 0xb4, 0x13, 0x3d, 0x38, 0x5b, 0x4e, 0x7a, 0x1d, 0xe5, 0x20, 0x4e, 0x71, 0x7c, 0xf8, - 0xb9, 0xe3, 0xd1, 0xbe, 0xa2, 0x90, 0xe5, 0xc8, 0xb5, 0xb7, 0x51, 0x06, 0x68, 0x85, 0xf3, 0x28, - 0xb3, 0xc9, 0x7c, 0x2f, 0x5d, 0xc0, 0x05, 0x94, 0xdb, 0x3c, 0xb0, 0xcd, 0x80, 0x58, 0x25, 0x0d, - 0xe7, 0xd0, 0xd4, 0xdd, 0xbb, 0x77, 0x4a, 0x29, 0xbc, 0x80, 0x4a, 0x6f, 0x10, 0xc3, 0xea, 0xd9, - 0x0e, 0xd9, 0x7c, 0xc4, 0x8f, 0x98, 0xd2, 0x14, 0x9e, 0x46, 0x7a, 0x8b, 0xec, 0x11, 0x68, 0x9c, - 0x5e, 0xfb, 0x54, 0x43, 0x19, 0x9e, 0x7c, 0x13, 0x54, 0x7c, 0x8b, 0x04, 0x9c, 0x0f, 0x80, 0xf8, - 0x18, 0xc7, 0xa7, 0x59, 0x4c, 0x91, 0xca, 0xc5, 0x11, 0xcf, 0x14, 0xce, 0xd6, 0xae, 0x7e, 0xef, - 0x93, 0x7f, 0xfc, 0x2c, 0xf5, 0x42, 0xad, 0xdc, 0x38, 0xf8, 0xff, 0xc6, 0x1e, 0xed, 0x5c, 0xf7, - 0x49, 0xd0, 0x78, 0x0c, 0x81, 0xf9, 0xa8, 0xf1, 0xd8, 0xb6, 0x3e, 0xba, 0xa9, 0x5d, 0x7b, 0x45, - 0xc3, 0x37, 0x51, 0x06, 0xc2, 0x8b, 0x39, 0x61, 0xe5, 0x50, 0x1f, 0x6f, 0x7b, 0xea, 0x07, 0x29, - 0x0d, 0x74, 0xb3, 0xb7, 0xe1, 0x67, 0x08, 0x78, 0xe9, 0x48, 0x2e, 0xbe, 0xc9, 0x82, 0x54, 0xe1, - 0x7b, 0x39, 0x6f, 0xb4, 0xb1, 0x4b, 0xcc, 0xfd, 0x16, 0xf1, 0x5d, 0xea, 0xf8, 0x64, 0xfd, 0xbd, - 0x3f, 0x3d, 0x59, 0xd6, 0x3e, 0x7e, 0xb2, 0xac, 0xfd, 0xed, 0xc9, 0xb2, 0xf6, 0xe3, 0xa7, 0xcb, - 0x17, 0x3e, 0x7e, 0xba, 0x7c, 0xe1, 0xaf, 0x4f, 0x97, 0x2f, 0x7c, 0xe7, 0xff, 0xba, 0x76, 0xb0, - 0x1b, 0x76, 0xea, 0x26, 0xed, 0x37, 0x0c, 0xaf, 0x6f, 0x58, 0x86, 0xeb, 0x51, 0x16, 0x20, 0xf1, - 0x57, 0xf4, 0xeb, 0x84, 0xdf, 0xa4, 0x16, 0x6e, 0x01, 0x70, 0x8f, 0x8b, 0xeb, 0x5b, 0xb4, 0x7e, - 0xcb, 0xb5, 0x3b, 0x59, 0xf0, 0xe1, 0xc6, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x01, 0x18, 0xb1, - 0x7b, 0x7c, 0x31, 0x00, 0x00, + // 2393 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcf, 0x6f, 0x1b, 0xc7, + 0xf5, 0xf7, 0x52, 0xfc, 0x39, 0x94, 0x44, 0x6a, 0xf4, 0xc3, 0x34, 0xed, 0x88, 0x02, 0x0d, 0xe4, + 0xab, 0x18, 0x31, 0x99, 0xaf, 0x9c, 0x14, 0x81, 0x51, 0xa0, 0xb0, 0x14, 0x25, 0x16, 0x1b, 0xd7, + 0x36, 0xe5, 0x20, 0x69, 0x11, 0x80, 0x5d, 0x72, 0x47, 0xd4, 0x4a, 0xe4, 0xce, 0x66, 0x76, 0x57, + 0xb6, 0x62, 0xe4, 0xd2, 0x5e, 0x7a, 0x28, 0x8a, 0xfe, 0x40, 0x6f, 0x45, 0xdb, 0x73, 0xd1, 0x53, + 0x2f, 0xbd, 0x15, 0x3d, 0x15, 0x45, 0x4f, 0x41, 0x73, 0xe9, 0x89, 0x68, 0xed, 0x22, 0x05, 0x88, + 0x1e, 0xfa, 0x27, 0x14, 0xf3, 0x66, 0x76, 0x39, 0xb3, 0xa2, 0x20, 0x59, 0xf9, 0x51, 0x43, 0xe1, + 0x29, 0xf1, 0xe7, 0xcd, 0x7b, 0xf3, 0xf6, 0xbd, 0xcf, 0xcc, 0xbc, 0xe1, 0x1b, 0xa1, 0x79, 0x77, + 0xbf, 0x5b, 0x37, 0x5d, 0xbb, 0x4e, 0x0e, 0x88, 0xe3, 0xd7, 0x5c, 0x46, 0x7d, 0x8a, 0xa7, 0x4c, + 0xd7, 0x2e, 0x57, 0xba, 0x94, 0x76, 0x7b, 0xa4, 0x0e, 0x50, 0x3b, 0xd8, 0xa9, 0xfb, 0x76, 0x9f, + 0x78, 0xbe, 0xd9, 0x77, 0xc5, 0xa8, 0xf2, 0x42, 0xa8, 0xea, 0x05, 0xed, 0xbe, 0xed, 0xc7, 0xd1, + 0x5d, 0x62, 0xf6, 0xfc, 0x5d, 0x89, 0x5e, 0x8e, 0x1b, 0x23, 0x7d, 0xd7, 0x3f, 0x94, 0xc2, 0x2b, + 0x52, 0xc8, 0xb5, 0x4c, 0xc7, 0xa1, 0xbe, 0xe9, 0xdb, 0xd4, 0xf1, 0xa4, 0xf4, 0xd5, 0xfd, 0xd7, + 0xbd, 0x9a, 0x4d, 0xb9, 0xb4, 0x6f, 0x76, 0x76, 0x6d, 0x87, 0xb0, 0xc3, 0x7a, 0x38, 0x09, 0x23, + 0x1e, 0x0d, 0x58, 0x87, 0xd4, 0xbb, 0xc4, 0x21, 0xcc, 0xf4, 0x89, 0x25, 0xb4, 0xaa, 0xbf, 0x48, + 0xa0, 0xb9, 0x06, 0x6d, 0x6f, 0x83, 0x6b, 0x3e, 0xb1, 0x36, 0xf9, 0xe7, 0xe1, 0x6b, 0x28, 0xbd, + 0x47, 0xdb, 0x2d, 0xdb, 0x2a, 0x19, 0x2b, 0xc6, 0x6a, 0x6e, 0x7d, 0x7e, 0x38, 0xa8, 0x14, 0xf6, + 0x68, 0x7b, 0xcb, 0x7a, 0x99, 0xf6, 0x6d, 0x1f, 0x9c, 0x6a, 0xa6, 0x00, 0xc0, 0xaf, 0x22, 0xc4, + 0xc7, 0x7a, 0xc4, 0xe7, 0xe3, 0x13, 0x30, 0x7e, 0x69, 0x38, 0xa8, 0xe0, 0x3d, 0xda, 0xde, 0x26, + 0xbe, 0xa6, 0x92, 0x0d, 0x31, 0xfc, 0x12, 0x4a, 0x7d, 0x10, 0x90, 0x80, 0x94, 0xa6, 0x46, 0x13, + 0x00, 0xa0, 0x4e, 0x00, 0x00, 0xfe, 0x26, 0xca, 0x74, 0x18, 0xe1, 0x3e, 0x97, 0x92, 0x2b, 0xc6, + 0x6a, 0x7e, 0xad, 0x5c, 0x13, 0x81, 0xa8, 0x85, 0x51, 0xaa, 0x3d, 0x08, 0x43, 0xbe, 0xbe, 0x38, + 0x1c, 0x54, 0xe6, 0xe4, 0x70, 0xc5, 0x54, 0x68, 0x01, 0x5f, 0x47, 0x53, 0x7b, 0xb4, 0x5d, 0x4a, + 0x81, 0xa1, 0x6c, 0xcd, 0x74, 0xed, 0x5a, 0x83, 0xb6, 0xd7, 0xe7, 0x86, 0x83, 0xca, 0xcc, 0x1e, + 0x6d, 0x2b, 0x2a, 0x7c, 0x5c, 0x75, 0x68, 0xa0, 0xd9, 0x06, 0x6d, 0xdf, 0xe7, 0x8e, 0x9c, 0xf7, + 0xd8, 0x54, 0xff, 0x92, 0x80, 0x8f, 0x7d, 0x9b, 0x98, 0xde, 0xf9, 0x27, 0xc2, 0xd7, 0x10, 0xea, + 0xf4, 0x02, 0xcf, 0x27, 0x8c, 0x7b, 0x9b, 0x82, 0xc9, 0x2f, 0x0e, 0x07, 0x95, 0x79, 0x89, 0x6a, + 0xee, 0xe6, 0x22, 0x10, 0xbf, 0x88, 0x92, 0x2e, 0xa5, 0xbd, 0x52, 0x1a, 0x34, 0xf0, 0x70, 0x50, + 0x99, 0xe5, 0xff, 0x56, 0x06, 0x83, 0xbc, 0xfa, 0x93, 0x24, 0x5a, 0x0c, 0x83, 0xd9, 0x24, 0x7e, + 0xc0, 0x9c, 0x49, 0x4c, 0x8f, 0x8b, 0xe9, 0xcb, 0x28, 0xcd, 0x88, 0xe9, 0x51, 0x47, 0x46, 0x75, + 0x61, 0x38, 0xa8, 0x14, 0x05, 0xa2, 0x28, 0xc8, 0x31, 0xf8, 0x1b, 0x68, 0x66, 0x3f, 0x68, 0x13, + 0xe6, 0x10, 0x9f, 0x78, 0x7c, 0xa2, 0x0c, 0x28, 0x95, 0x87, 0x83, 0xca, 0xd2, 0x48, 0xa0, 0xcd, + 0x35, 0xad, 0xe2, 0xdc, 0x4d, 0x97, 0x5a, 0x2d, 0x27, 0xe8, 0xb7, 0x09, 0x2b, 0x65, 0x57, 0x8c, + 0xd5, 0x94, 0x70, 0xd3, 0xa5, 0xd6, 0xb7, 0x00, 0x54, 0xdd, 0x8c, 0x40, 0x3e, 0x31, 0x0b, 0x9c, + 0x96, 0xe9, 0x83, 0x88, 0x58, 0xa5, 0xdc, 0x8a, 0xb1, 0x9a, 0x15, 0x13, 0xb3, 0xc0, 0xb9, 0x15, + 0xe2, 0xea, 0xc4, 0x2a, 0x5e, 0xfd, 0x8f, 0x81, 0x16, 0x42, 0x4e, 0x6c, 0x3e, 0x72, 0x6d, 0x76, + 0xfe, 0xf7, 0x94, 0xdf, 0x27, 0x51, 0xa1, 0x41, 0xdb, 0xf7, 0x88, 0x63, 0xd9, 0x4e, 0x77, 0xb2, + 0x00, 0xc6, 0x2f, 0x80, 0x23, 0x94, 0x4e, 0x7f, 0x26, 0x4a, 0x67, 0x4e, 0x4d, 0xe9, 0x57, 0x50, + 0x16, 0xf4, 0xcc, 0x3e, 0x81, 0x85, 0x90, 0x13, 0x9f, 0xc8, 0x07, 0x98, 0x7d, 0x35, 0x5a, 0x19, + 0x09, 0x71, 0x57, 0x43, 0x0d, 0xcf, 0x35, 0x3b, 0x04, 0x16, 0x81, 0x74, 0x55, 0x8e, 0x01, 0x5c, + 0x75, 0x55, 0xc5, 0xa3, 0x0d, 0x14, 0x9d, 0xb0, 0x81, 0xfe, 0x5b, 0x30, 0xa7, 0x19, 0x38, 0xce, + 0x84, 0x39, 0x5f, 0x1c, 0x73, 0x6e, 0xa0, 0x9c, 0x43, 0x2d, 0x22, 0x28, 0x90, 0x19, 0x45, 0x89, + 0x83, 0x31, 0x0e, 0x64, 0x43, 0xec, 0xcc, 0x3b, 0xa8, 0x4a, 0xb7, 0xdc, 0xd9, 0xe8, 0x86, 0xce, + 0x48, 0xb7, 0xfc, 0x09, 0x74, 0xfb, 0x5d, 0x1a, 0xcd, 0x37, 0x68, 0x7b, 0xcb, 0xe9, 0x32, 0xe2, + 0x79, 0x5b, 0xce, 0x0e, 0x9d, 0x50, 0xee, 0xbc, 0x51, 0x0e, 0x9d, 0x8d, 0x72, 0xf9, 0x67, 0xa4, + 0xdc, 0x63, 0x34, 0x67, 0x0b, 0x1a, 0xb5, 0x4c, 0xcb, 0xe2, 0xff, 0x25, 0x5e, 0x29, 0xb7, 0x32, + 0xb5, 0x9a, 0x5f, 0xab, 0x85, 0x37, 0x8e, 0x38, 0xcf, 0x6a, 0x12, 0xb8, 0x15, 0x2a, 0x6c, 0x3a, + 0x3e, 0x3b, 0x5c, 0x5f, 0x1e, 0x0e, 0x2a, 0x65, 0x3b, 0x26, 0x52, 0x26, 0x2e, 0xc6, 0x65, 0xe5, + 0x7d, 0xb4, 0x38, 0xd6, 0x14, 0xbe, 0x8a, 0xa6, 0xf6, 0xc9, 0x21, 0xb0, 0x38, 0x25, 0xee, 0x3b, + 0xfb, 0xe4, 0x50, 0xbd, 0xef, 0xec, 0x93, 0x43, 0xce, 0xc5, 0x03, 0xb3, 0x17, 0x10, 0x49, 0x5e, + 0xe0, 0x22, 0x00, 0x2a, 0x17, 0x01, 0xb8, 0x99, 0x78, 0xdd, 0xa8, 0xfe, 0x36, 0x07, 0x37, 0x86, + 0x37, 0x4d, 0xbb, 0x37, 0xa9, 0x6e, 0x3f, 0x9f, 0xea, 0xf6, 0x7d, 0x84, 0xc8, 0x23, 0xdb, 0x6f, + 0x75, 0xa8, 0x45, 0xbc, 0x52, 0x06, 0x58, 0x53, 0x0d, 0x59, 0xa3, 0x04, 0xba, 0xb6, 0xf9, 0xc8, + 0xf6, 0x37, 0xf8, 0x20, 0xc1, 0x94, 0x4b, 0xdc, 0x13, 0x12, 0x62, 0x23, 0xc3, 0x25, 0xa3, 0x99, + 0x8b, 0xe0, 0xa3, 0x6b, 0x37, 0xfb, 0x59, 0xd6, 0x6e, 0xee, 0x4c, 0x6b, 0x17, 0x9d, 0x69, 0xed, + 0xce, 0x9c, 0x6d, 0xed, 0xce, 0x3e, 0xe3, 0xda, 0xb5, 0x10, 0xee, 0x50, 0xc7, 0x37, 0x6d, 0x87, + 0xb0, 0x96, 0xe7, 0x9b, 0x7e, 0xc0, 0x17, 0x6f, 0x1e, 0xd2, 0xb0, 0x00, 0x69, 0xd8, 0x08, 0xc5, + 0xdb, 0x20, 0x5d, 0xaf, 0x0c, 0x07, 0x95, 0xcb, 0x1d, 0x1d, 0xd4, 0xd6, 0xe8, 0xdc, 0x11, 0x21, + 0x7e, 0x0d, 0xa5, 0x3a, 0x66, 0xe0, 0x91, 0xd2, 0xf4, 0x8a, 0xb1, 0x3a, 0xbb, 0x86, 0x84, 0x61, + 0x8e, 0x08, 0x3a, 0x83, 0x50, 0xa5, 0x33, 0x00, 0xf8, 0x36, 0x2a, 0xee, 0x98, 0x76, 0x2f, 0x60, + 0xa4, 0xd5, 0x31, 0x7d, 0xd2, 0xa5, 0xec, 0xb0, 0x54, 0x84, 0x0f, 0x7c, 0x61, 0x38, 0xa8, 0x5c, + 0x92, 0xb2, 0x0d, 0x29, 0x52, 0xf4, 0x0b, 0x31, 0x11, 0xbe, 0x8f, 0xe6, 0x43, 0x4b, 0x5e, 0xd0, + 0x8e, 0x8c, 0xcd, 0x81, 0xb1, 0x95, 0xe1, 0xa0, 0x72, 0x45, 0x8a, 0xb7, 0x47, 0x52, 0xc5, 0x1e, + 0x3e, 0x2a, 0xc5, 0xaf, 0xa1, 0x1c, 0x23, 0x3e, 0x3b, 0x34, 0xdb, 0x3d, 0x52, 0xc2, 0x70, 0x33, + 0x82, 0x1c, 0x47, 0xa0, 0x9a, 0xe3, 0x08, 0x2c, 0x5b, 0x68, 0x56, 0x67, 0xb2, 0xba, 0x51, 0xe5, + 0x4e, 0xb7, 0x51, 0xa5, 0x4e, 0xda, 0xa8, 0x1a, 0xc9, 0x6c, 0xa1, 0x58, 0xac, 0x7e, 0x92, 0x40, + 0x98, 0x5f, 0x46, 0x18, 0xe1, 0x03, 0xbe, 0x02, 0x55, 0x25, 0xe4, 0xe4, 0x83, 0x80, 0x78, 0x3e, + 0x65, 0xea, 0x8e, 0x15, 0x81, 0x7a, 0x4e, 0x24, 0xf8, 0x6c, 0x3b, 0x56, 0xf5, 0xe7, 0x49, 0xf8, + 0x09, 0x51, 0x46, 0x75, 0x72, 0x0e, 0x1c, 0x77, 0x0e, 0x5c, 0x43, 0x69, 0x16, 0x38, 0xa3, 0x82, + 0x09, 0x1c, 0x66, 0x81, 0xa3, 0x47, 0x04, 0x00, 0xbc, 0x85, 0xe6, 0x5c, 0xc9, 0xd2, 0x03, 0xd2, + 0x92, 0x81, 0xcc, 0x8c, 0x96, 0xfa, 0x48, 0xd8, 0x88, 0x85, 0xb4, 0x10, 0x13, 0xc5, 0x4c, 0x49, + 0x0f, 0xb2, 0xe3, 0x4c, 0x35, 0x63, 0xbe, 0x14, 0x62, 0x22, 0x85, 0x17, 0xb9, 0x53, 0xf0, 0xe2, + 0x4f, 0x49, 0xf9, 0xd3, 0x72, 0xa7, 0x43, 0x88, 0x35, 0xe1, 0xc5, 0xe4, 0x0a, 0x77, 0xb6, 0x2b, + 0x5c, 0xf5, 0x1f, 0x79, 0xb8, 0x9a, 0xbd, 0xe3, 0xdb, 0x3d, 0xdb, 0x83, 0x9e, 0xc7, 0x84, 0x4a, + 0x5f, 0x10, 0x95, 0x7e, 0x64, 0xa0, 0xc5, 0x3b, 0xe6, 0xa3, 0xa6, 0x6c, 0x17, 0x79, 0x6f, 0x52, + 0x76, 0x8f, 0x30, 0x9b, 0x5a, 0xb2, 0x12, 0xbd, 0x11, 0x56, 0xa2, 0xf1, 0x64, 0xd4, 0xc6, 0x6a, + 0x89, 0xd2, 0xf4, 0xea, 0x70, 0x50, 0xa9, 0x8c, 0x95, 0x2b, 0x7e, 0x8c, 0x9f, 0x56, 0xe7, 0x76, + 0xf6, 0x4c, 0xdc, 0xce, 0x3d, 0xcf, 0x77, 0xc5, 0x1f, 0x1a, 0x68, 0xc9, 0xa7, 0xbe, 0xd9, 0x6b, + 0x75, 0x82, 0x7e, 0xd0, 0x33, 0x61, 0x93, 0x0e, 0x3c, 0xb3, 0xcb, 0x6b, 0x43, 0x1e, 0xf1, 0xb5, + 0x63, 0x23, 0xfe, 0x80, 0xab, 0x6d, 0x44, 0x5a, 0xef, 0x70, 0x25, 0x11, 0xf0, 0xea, 0x70, 0x50, + 0x59, 0xf6, 0xc7, 0x88, 0x15, 0x37, 0x16, 0xc6, 0xc9, 0x21, 0xff, 0xb7, 0x0e, 0xba, 0x63, 0xf2, + 0x3f, 0x73, 0x42, 0xfe, 0xc7, 0x6a, 0x29, 0xf9, 0x1f, 0x2b, 0x57, 0xf3, 0x3f, 0x76, 0x40, 0xf9, + 0xd7, 0x06, 0x2a, 0x1f, 0x4f, 0xad, 0xd3, 0xd5, 0x8a, 0xdf, 0x56, 0x6b, 0x45, 0x7e, 0x07, 0x17, + 0x9d, 0xd2, 0x9a, 0xda, 0x29, 0xad, 0xb9, 0xfb, 0x5d, 0xf8, 0xb6, 0xb0, 0x53, 0x5a, 0xbb, 0x1f, + 0x98, 0x8e, 0x6f, 0xfb, 0x87, 0x27, 0xd5, 0x96, 0xe5, 0x5f, 0x19, 0xe8, 0xd2, 0xb1, 0xb9, 0x78, + 0x2e, 0x3c, 0xe4, 0x41, 0x3c, 0x3e, 0x3f, 0xcf, 0x83, 0x8b, 0xd5, 0x7f, 0x25, 0xd0, 0x52, 0x83, + 0xb6, 0x9b, 0xc4, 0x65, 0x36, 0x65, 0xb6, 0x6f, 0x7f, 0xf8, 0x15, 0x28, 0xcf, 0xbf, 0x8e, 0xa6, + 0x1d, 0xf2, 0xb0, 0x25, 0x3f, 0xf9, 0x10, 0x36, 0x7a, 0x03, 0x6e, 0xf2, 0x8b, 0x0e, 0x79, 0x78, + 0x4f, 0xc2, 0x8a, 0x66, 0x5e, 0x81, 0xf5, 0xe2, 0x3e, 0x7d, 0xda, 0xe2, 0xbe, 0xfa, 0x69, 0x02, + 0x1a, 0x93, 0x4a, 0xa4, 0xcf, 0x7f, 0x69, 0xf6, 0x3f, 0x09, 0xb4, 0xbc, 0x6d, 0x6e, 0x98, 0x4e, + 0x87, 0xf4, 0x7a, 0x93, 0xdb, 0xe6, 0xe7, 0x73, 0xdb, 0xfc, 0xab, 0x78, 0xb0, 0x22, 0xa3, 0x7a, + 0xfe, 0xa9, 0xfb, 0xa5, 0x04, 0xf5, 0x8f, 0x49, 0xa0, 0xea, 0x03, 0xc2, 0xfa, 0xb6, 0x63, 0x4e, + 0xee, 0xf0, 0xcf, 0x77, 0xa3, 0xf6, 0x4b, 0xea, 0x9c, 0x8d, 0x28, 0x94, 0x3d, 0x05, 0x85, 0xfe, + 0x90, 0x47, 0xd3, 0xc0, 0x9a, 0x3b, 0xc4, 0x83, 0x52, 0xf2, 0x2e, 0xca, 0x79, 0xe1, 0xab, 0x32, + 0xe0, 0x4f, 0x7e, 0x6d, 0x29, 0xac, 0x1e, 0xf5, 0xe7, 0x66, 0x22, 0x00, 0xd1, 0xe0, 0x91, 0xf1, + 0xdb, 0x17, 0x9a, 0x23, 0x1b, 0x78, 0x03, 0xa5, 0x81, 0x09, 0x96, 0x2c, 0x41, 0xe6, 0x43, 0x6b, + 0xca, 0xeb, 0x2c, 0xe1, 0xa4, 0x18, 0xa6, 0xd9, 0x91, 0xaa, 0xdc, 0x48, 0x0f, 0xde, 0x37, 0x01, + 0xe3, 0x14, 0x23, 0xca, 0xab, 0x27, 0x61, 0x44, 0x0c, 0xd3, 0x8d, 0x08, 0x0c, 0x7f, 0x17, 0xcd, + 0xc2, 0xff, 0xb5, 0x98, 0x7c, 0xd8, 0x13, 0x31, 0x52, 0x35, 0xa6, 0xbd, 0xfa, 0x59, 0xbf, 0x3c, + 0x1c, 0x54, 0x2e, 0xf6, 0x54, 0x5c, 0x33, 0x3d, 0xa3, 0x89, 0xf0, 0xfb, 0x48, 0x00, 0x2d, 0x22, + 0x9e, 0x89, 0xc8, 0x07, 0x6b, 0x97, 0xb4, 0x09, 0xd4, 0x27, 0x24, 0x22, 0xaf, 0x3d, 0x05, 0xd6, + 0xcc, 0x4f, 0xab, 0x12, 0xfc, 0x16, 0xca, 0xb8, 0xe2, 0x41, 0x06, 0xf0, 0x37, 0xfc, 0x65, 0x3b, + 0xf6, 0x4e, 0x43, 0x32, 0x4c, 0x20, 0x9a, 0xb5, 0x50, 0x9b, 0x1b, 0x62, 0xa2, 0x3f, 0x0f, 0x54, + 0x56, 0x0c, 0xa9, 0x6d, 0x7b, 0x61, 0x48, 0x0e, 0xd4, 0x0d, 0x49, 0x90, 0xa7, 0x65, 0x07, 0x7a, + 0x1b, 0x40, 0x6e, 0x25, 0x2d, 0x4a, 0xc7, 0x43, 0xa4, 0x45, 0x0c, 0xd3, 0xd3, 0x22, 0x30, 0xc1, + 0x38, 0xf9, 0x63, 0x13, 0xb0, 0x5d, 0x63, 0x9c, 0xfa, 0x2b, 0x54, 0xc8, 0x38, 0x89, 0xc5, 0x19, + 0x27, 0x61, 0xdc, 0x42, 0x33, 0x4c, 0x2d, 0x93, 0xe0, 0x76, 0xa7, 0xa4, 0xf9, 0x68, 0x0d, 0x25, + 0xd2, 0xac, 0x29, 0xe9, 0x69, 0xd6, 0x44, 0x78, 0x1b, 0xa1, 0x4e, 0x54, 0x1e, 0x40, 0x33, 0x20, + 0xbf, 0x76, 0x31, 0xb4, 0x1e, 0x2b, 0x1c, 0xd6, 0x4b, 0xc3, 0x41, 0x65, 0x61, 0x34, 0x5c, 0xb3, + 0xab, 0x98, 0xe1, 0x61, 0xe8, 0x84, 0xa7, 0x23, 0xb4, 0x4d, 0x94, 0x30, 0xe8, 0xc7, 0xa6, 0xdc, + 0xf2, 0x42, 0x4c, 0x0f, 0x43, 0x04, 0xe3, 0x77, 0x51, 0x3e, 0x18, 0x5d, 0xf7, 0x4a, 0x05, 0x30, + 0x59, 0x3a, 0xee, 0x26, 0x28, 0xca, 0x2a, 0x45, 0x41, 0x33, 0xab, 0x5a, 0xc2, 0xef, 0xa1, 0xe9, + 0xb0, 0x51, 0x6a, 0x3b, 0x3b, 0x14, 0xda, 0x0f, 0x8a, 0xe5, 0x78, 0x8f, 0x54, 0x58, 0xb6, 0x47, + 0xa8, 0x6e, 0x59, 0x11, 0xe0, 0x0e, 0x9a, 0x65, 0xda, 0x55, 0x02, 0x3a, 0x12, 0xf9, 0xb5, 0xcb, + 0x63, 0x52, 0x17, 0x05, 0xf8, 0xca, 0x70, 0x50, 0x29, 0xe9, 0x6a, 0xda, 0x0c, 0x31, 0x93, 0x3c, + 0xd0, 0x6e, 0xf8, 0xa3, 0x77, 0x69, 0x51, 0x0f, 0xb4, 0xfe, 0x6b, 0xb8, 0xdc, 0xe2, 0x43, 0x4c, + 0x0f, 0x74, 0x04, 0x73, 0x3a, 0xb8, 0x51, 0x6f, 0xa2, 0xb4, 0xa4, 0xd3, 0x21, 0xd6, 0xb5, 0x10, + 0x74, 0x18, 0x0d, 0xd7, 0xe9, 0x30, 0xc2, 0xd7, 0xb3, 0x28, 0x0d, 0x6f, 0x96, 0xbd, 0x46, 0x32, + 0x9b, 0x2d, 0xe6, 0x1a, 0xc9, 0xec, 0x6c, 0xb1, 0xd0, 0x48, 0x66, 0x8b, 0xc5, 0xb9, 0x46, 0x32, + 0x3b, 0x5f, 0x5c, 0x68, 0x24, 0xb3, 0x0b, 0xc5, 0xc5, 0xea, 0xf7, 0x13, 0xa8, 0x10, 0xeb, 0x6d, + 0xe1, 0x17, 0x51, 0x12, 0x4e, 0x1c, 0x63, 0xf4, 0x78, 0xc2, 0xd1, 0x8f, 0x1b, 0x90, 0xe3, 0x35, + 0x94, 0x0d, 0x7b, 0x8c, 0xb2, 0x21, 0x03, 0x47, 0x7f, 0x88, 0xa9, 0x47, 0x7f, 0x88, 0xe1, 0x3a, + 0xca, 0xf4, 0xc5, 0x51, 0x21, 0x0f, 0x7f, 0xd8, 0x25, 0x24, 0xa4, 0x1e, 0x68, 0x12, 0x52, 0xce, + 0xa3, 0xe4, 0x29, 0xfa, 0xa8, 0x51, 0x8b, 0x2d, 0xf5, 0x2c, 0x2d, 0xb6, 0xea, 0x87, 0x08, 0x43, + 0x78, 0xb7, 0x7d, 0x46, 0xcc, 0x7e, 0x78, 0x96, 0xad, 0xa0, 0x44, 0x54, 0x04, 0x15, 0x87, 0x83, + 0xca, 0xb4, 0xad, 0x9e, 0xf0, 0x09, 0xdb, 0xc2, 0xeb, 0xa3, 0xaf, 0x11, 0xa7, 0xd3, 0x1c, 0x4c, + 0xa8, 0x9e, 0x88, 0x27, 0x7d, 0x60, 0xf5, 0xa7, 0x09, 0x34, 0xd3, 0x80, 0xca, 0xa8, 0x29, 0xea, + 0xb8, 0x53, 0xcc, 0xfb, 0x12, 0x4a, 0x3d, 0x34, 0xfd, 0xce, 0x2e, 0xcc, 0x9a, 0x15, 0x9f, 0x06, + 0x80, 0xfa, 0x69, 0x00, 0xe0, 0x0d, 0x54, 0xd8, 0x61, 0xb4, 0xdf, 0x92, 0xd3, 0xf1, 0xea, 0x45, + 0x04, 0x1e, 0xf6, 0x2c, 0x2e, 0x92, 0x8e, 0x6a, 0xe5, 0xcb, 0x8c, 0x26, 0x18, 0x15, 0x6c, 0xc9, + 0x13, 0x0b, 0xb6, 0x37, 0xd0, 0x2c, 0x61, 0x8c, 0xb2, 0xad, 0x9d, 0x3b, 0xb6, 0xe7, 0x71, 0x46, + 0xa7, 0xc0, 0x47, 0x58, 0x66, 0xba, 0x44, 0x51, 0x8e, 0xe9, 0x54, 0x7f, 0x69, 0xa0, 0xe9, 0x77, + 0xb9, 0xff, 0x61, 0x4c, 0x22, 0x0f, 0x8c, 0x13, 0x3d, 0x38, 0x5b, 0x4d, 0x7a, 0x1d, 0x65, 0x20, + 0x4e, 0x51, 0x7c, 0xc4, 0xb9, 0xc3, 0x68, 0x5f, 0x53, 0x48, 0x0b, 0xe4, 0xda, 0xdb, 0x28, 0x05, + 0xb4, 0xc2, 0x39, 0x94, 0xda, 0xe4, 0xbe, 0x17, 0x2f, 0xe0, 0x3c, 0xca, 0x6c, 0x1e, 0xd8, 0x1d, + 0x9f, 0x58, 0x45, 0x03, 0x67, 0xd0, 0xd4, 0xdd, 0xbb, 0x77, 0x8a, 0x09, 0xbc, 0x80, 0x8a, 0x6f, + 0x10, 0xd3, 0xea, 0xd9, 0x0e, 0xd9, 0x7c, 0x24, 0x8e, 0x98, 0xe2, 0x14, 0x9e, 0x46, 0xd9, 0x26, + 0xd9, 0x23, 0x30, 0x38, 0xb9, 0xf6, 0xa9, 0x81, 0x52, 0xa2, 0xf8, 0x26, 0xa8, 0xf0, 0x16, 0xf1, + 0x05, 0x1f, 0x00, 0xf1, 0x30, 0x8e, 0x4e, 0xb3, 0x88, 0x22, 0xe5, 0x8b, 0x23, 0x9e, 0x69, 0x9c, + 0xad, 0x5e, 0xfd, 0xde, 0x27, 0xff, 0xfc, 0x59, 0xe2, 0x85, 0x6a, 0xa9, 0x7e, 0xf0, 0xff, 0xf5, + 0x3d, 0xda, 0xbe, 0xee, 0x11, 0xbf, 0xfe, 0x18, 0x02, 0xf3, 0x51, 0xfd, 0xb1, 0x6d, 0x7d, 0x74, + 0xd3, 0xb8, 0xf6, 0x8a, 0x81, 0x6f, 0xa2, 0x14, 0x84, 0x17, 0x0b, 0xc2, 0xaa, 0xa1, 0x3e, 0xde, + 0xf6, 0xd4, 0x0f, 0x12, 0x06, 0xe8, 0xa6, 0x6f, 0xc3, 0x5f, 0x2f, 0xe0, 0xa5, 0x23, 0xb5, 0xf8, + 0x26, 0x0f, 0x52, 0x59, 0xec, 0xe5, 0x62, 0xd0, 0xc6, 0x2e, 0xe9, 0xec, 0x37, 0x89, 0xe7, 0x52, + 0xc7, 0x23, 0xeb, 0xef, 0xfd, 0xf9, 0xc9, 0xb2, 0xf1, 0xf1, 0x93, 0x65, 0xe3, 0xef, 0x4f, 0x96, + 0x8d, 0x1f, 0x3f, 0x5d, 0xbe, 0xf0, 0xf1, 0xd3, 0xe5, 0x0b, 0x7f, 0x7b, 0xba, 0x7c, 0xe1, 0x3b, + 0xff, 0xd7, 0xb5, 0xfd, 0xdd, 0xa0, 0x5d, 0xeb, 0xd0, 0x7e, 0xdd, 0x64, 0x7d, 0xd3, 0x32, 0x5d, + 0x46, 0x79, 0x80, 0xe4, 0xbf, 0xc2, 0x3f, 0x6a, 0xf8, 0x4d, 0x62, 0xe1, 0x16, 0x00, 0xf7, 0x84, + 0xb8, 0xb6, 0x45, 0x6b, 0xb7, 0x5c, 0xbb, 0x9d, 0x06, 0x1f, 0x6e, 0xfc, 0x37, 0x00, 0x00, 0xff, + 0xff, 0xc8, 0xfc, 0x1a, 0x0d, 0xb3, 0x31, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3513,6 +3527,18 @@ func (m *JobFailedEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Retryable { + i-- + if m.Retryable { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x90 + } if len(m.FailureSubcategory) > 0 { i -= len(m.FailureSubcategory) copy(dAtA[i:], m.FailureSubcategory) @@ -5452,6 +5478,9 @@ func (m *JobFailedEvent) Size() (n int) { if l > 0 { n += 2 + l + sovEvent(uint64(l)) } + if m.Retryable { + n += 3 + } return n } @@ -9135,6 +9164,26 @@ func (m *JobFailedEvent) Unmarshal(dAtA []byte) error { } m.FailureSubcategory = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 18: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Retryable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Retryable = bool(v != 0) default: iNdEx = preIndex skippy, err := skipEvent(dAtA[iNdEx:]) diff --git a/pkg/api/event.proto b/pkg/api/event.proto index 8a8e09de313..96a744f04ba 100644 --- a/pkg/api/event.proto +++ b/pkg/api/event.proto @@ -113,6 +113,12 @@ message JobFailedEvent { reserved 15; string failure_category = 16; string failure_subcategory = 17; + // retryable indicates the scheduler emitted this failure for an + // intermediate (non-terminal) run that will be retried. When true, + // a subsequent leased/succeeded/failed event for the same job is + // expected. Default false preserves the prior behavior where every + // emitted JobFailedEvent was terminal. + bool retryable = 18; } message JobPreemptingEvent { diff --git a/pkg/api/submit.pb.go b/pkg/api/submit.pb.go index 02fbb77937c..bd3e74660b3 100644 --- a/pkg/api/submit.pb.go +++ b/pkg/api/submit.pb.go @@ -133,6 +133,62 @@ func (JobState) EnumDescriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{2} } +type RetryAction int32 + +const ( + RetryAction_RETRY_ACTION_UNSPECIFIED RetryAction = 0 + RetryAction_RETRY_ACTION_FAIL RetryAction = 1 + RetryAction_RETRY_ACTION_RETRY RetryAction = 2 +) + +var RetryAction_name = map[int32]string{ + 0: "RETRY_ACTION_UNSPECIFIED", + 1: "RETRY_ACTION_FAIL", + 2: "RETRY_ACTION_RETRY", +} + +var RetryAction_value = map[string]int32{ + "RETRY_ACTION_UNSPECIFIED": 0, + "RETRY_ACTION_FAIL": 1, + "RETRY_ACTION_RETRY": 2, +} + +func (x RetryAction) String() string { + return proto.EnumName(RetryAction_name, int32(x)) +} + +func (RetryAction) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{3} +} + +type ExitCodeOperator int32 + +const ( + ExitCodeOperator_EXIT_CODE_OPERATOR_UNSPECIFIED ExitCodeOperator = 0 + ExitCodeOperator_EXIT_CODE_OPERATOR_IN ExitCodeOperator = 1 + ExitCodeOperator_EXIT_CODE_OPERATOR_NOT_IN ExitCodeOperator = 2 +) + +var ExitCodeOperator_name = map[int32]string{ + 0: "EXIT_CODE_OPERATOR_UNSPECIFIED", + 1: "EXIT_CODE_OPERATOR_IN", + 2: "EXIT_CODE_OPERATOR_NOT_IN", +} + +var ExitCodeOperator_value = map[string]int32{ + "EXIT_CODE_OPERATOR_UNSPECIFIED": 0, + "EXIT_CODE_OPERATOR_IN": 1, + "EXIT_CODE_OPERATOR_NOT_IN": 2, +} + +func (x ExitCodeOperator) String() string { + return proto.EnumName(ExitCodeOperator_name, int32(x)) +} + +func (ExitCodeOperator) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{4} +} + type JobSubmitRequestItem struct { Priority float64 `protobuf:"fixed64,1,opt,name=priority,proto3" json:"priority,omitempty"` Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` @@ -1189,6 +1245,7 @@ type Queue struct { // A list of Kubernetes-like key-value labels, e.g. armadaproject.io/priority=critical LabelsDeprecated []string `protobuf:"bytes,9,rep,name=labels_deprecated,json=labelsDeprecated,proto3" json:"labelsDeprecated,omitempty"` // Deprecated: Do not use. Labels map[string]string `protobuf:"bytes,10,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + RetryPolicy string `protobuf:"bytes,11,opt,name=retry_policy,json=retryPolicy,proto3" json:"retryPolicy,omitempty"` } func (m *Queue) Reset() { *m = Queue{} } @@ -1296,6 +1353,13 @@ func (m *Queue) GetLabels() map[string]string { return nil } +func (m *Queue) GetRetryPolicy() string { + if m != nil { + return m.RetryPolicy + } + return "" +} + type Queue_Permissions struct { Subjects []*Queue_Permissions_Subject `protobuf:"bytes,1,rep,name=subjects,proto3" json:"subjects,omitempty"` Verbs []string `protobuf:"bytes,2,rep,name=verbs,proto3" json:"verbs,omitempty"` @@ -1635,23 +1699,30 @@ func (m *PreemptionResult) GetPreemptionResults() map[string]string { return nil } -//swagger:model -type QueueGetRequest struct { +// RetryPolicy defines rules that determine whether failed jobs should be retried. +// Operators create policies and assign them to queues by name. +type RetryPolicy struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (m *QueueGetRequest) Reset() { *m = QueueGetRequest{} } -func (m *QueueGetRequest) String() string { return proto.CompactTextString(m) } -func (*QueueGetRequest) ProtoMessage() {} -func (*QueueGetRequest) Descriptor() ([]byte, []int) { + // retry_limit is the maximum number of retries after the initial failure. + // retry_limit: 3 allows up to 3 retries (4 total attempts before terminal + // failure). 0 means unlimited, subject to the scheduler's global cap. + RetryLimit uint32 `protobuf:"varint,2,opt,name=retry_limit,json=retryLimit,proto3" json:"retryLimit,omitempty"` + DefaultAction RetryAction `protobuf:"varint,3,opt,name=default_action,json=defaultAction,proto3,enum=api.RetryAction" json:"defaultAction,omitempty"` + Rules []*RetryRule `protobuf:"bytes,4,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (m *RetryPolicy) Reset() { *m = RetryPolicy{} } +func (m *RetryPolicy) String() string { return proto.CompactTextString(m) } +func (*RetryPolicy) ProtoMessage() {} +func (*RetryPolicy) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{19} } -func (m *QueueGetRequest) XXX_Unmarshal(b []byte) error { +func (m *RetryPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueueGetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *RetryPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueueGetRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_RetryPolicy.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1661,42 +1732,69 @@ func (m *QueueGetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, err return b[:n], nil } } -func (m *QueueGetRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueueGetRequest.Merge(m, src) +func (m *RetryPolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryPolicy.Merge(m, src) } -func (m *QueueGetRequest) XXX_Size() int { +func (m *RetryPolicy) XXX_Size() int { return m.Size() } -func (m *QueueGetRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueueGetRequest.DiscardUnknown(m) +func (m *RetryPolicy) XXX_DiscardUnknown() { + xxx_messageInfo_RetryPolicy.DiscardUnknown(m) } -var xxx_messageInfo_QueueGetRequest proto.InternalMessageInfo +var xxx_messageInfo_RetryPolicy proto.InternalMessageInfo -func (m *QueueGetRequest) GetName() string { +func (m *RetryPolicy) GetName() string { if m != nil { return m.Name } return "" } -//swagger:model -type QueueCordonRequest struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +func (m *RetryPolicy) GetRetryLimit() uint32 { + if m != nil { + return m.RetryLimit + } + return 0 } -func (m *QueueCordonRequest) Reset() { *m = QueueCordonRequest{} } -func (m *QueueCordonRequest) String() string { return proto.CompactTextString(m) } -func (*QueueCordonRequest) ProtoMessage() {} -func (*QueueCordonRequest) Descriptor() ([]byte, []int) { +func (m *RetryPolicy) GetDefaultAction() RetryAction { + if m != nil { + return m.DefaultAction + } + return RetryAction_RETRY_ACTION_UNSPECIFIED +} + +func (m *RetryPolicy) GetRules() []*RetryRule { + if m != nil { + return m.Rules + } + return nil +} + +type RetryRule struct { + Action RetryAction `protobuf:"varint,1,opt,name=action,proto3,enum=api.RetryAction" json:"action,omitempty"` + OnConditions []string `protobuf:"bytes,2,rep,name=on_conditions,json=onConditions,proto3" json:"onConditions,omitempty"` + OnExitCodes *RetryExitCodeMatcher `protobuf:"bytes,3,opt,name=on_exit_codes,json=onExitCodes,proto3" json:"onExitCodes,omitempty"` + OnTerminationMessagePattern string `protobuf:"bytes,4,opt,name=on_termination_message_pattern,json=onTerminationMessagePattern,proto3" json:"onTerminationMessagePattern,omitempty"` + // on_category matches against Error.failure_category. When set with on_subcategory, + // both must match. Mirrors the engine's Rule.OnCategory / Rule.OnSubcategory. + OnCategory string `protobuf:"bytes,5,opt,name=on_category,json=onCategory,proto3" json:"onCategory,omitempty"` + OnSubcategory string `protobuf:"bytes,6,opt,name=on_subcategory,json=onSubcategory,proto3" json:"onSubcategory,omitempty"` +} + +func (m *RetryRule) Reset() { *m = RetryRule{} } +func (m *RetryRule) String() string { return proto.CompactTextString(m) } +func (*RetryRule) ProtoMessage() {} +func (*RetryRule) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{20} } -func (m *QueueCordonRequest) XXX_Unmarshal(b []byte) error { +func (m *RetryRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueueCordonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *RetryRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueueCordonRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_RetryRule.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1706,42 +1804,77 @@ func (m *QueueCordonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueueCordonRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueueCordonRequest.Merge(m, src) +func (m *RetryRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryRule.Merge(m, src) } -func (m *QueueCordonRequest) XXX_Size() int { +func (m *RetryRule) XXX_Size() int { return m.Size() } -func (m *QueueCordonRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueueCordonRequest.DiscardUnknown(m) +func (m *RetryRule) XXX_DiscardUnknown() { + xxx_messageInfo_RetryRule.DiscardUnknown(m) } -var xxx_messageInfo_QueueCordonRequest proto.InternalMessageInfo +var xxx_messageInfo_RetryRule proto.InternalMessageInfo -func (m *QueueCordonRequest) GetName() string { +func (m *RetryRule) GetAction() RetryAction { if m != nil { - return m.Name + return m.Action + } + return RetryAction_RETRY_ACTION_UNSPECIFIED +} + +func (m *RetryRule) GetOnConditions() []string { + if m != nil { + return m.OnConditions + } + return nil +} + +func (m *RetryRule) GetOnExitCodes() *RetryExitCodeMatcher { + if m != nil { + return m.OnExitCodes + } + return nil +} + +func (m *RetryRule) GetOnTerminationMessagePattern() string { + if m != nil { + return m.OnTerminationMessagePattern } return "" } -//swagger:model -type QueueUncordonRequest struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +func (m *RetryRule) GetOnCategory() string { + if m != nil { + return m.OnCategory + } + return "" } -func (m *QueueUncordonRequest) Reset() { *m = QueueUncordonRequest{} } -func (m *QueueUncordonRequest) String() string { return proto.CompactTextString(m) } -func (*QueueUncordonRequest) ProtoMessage() {} -func (*QueueUncordonRequest) Descriptor() ([]byte, []int) { +func (m *RetryRule) GetOnSubcategory() string { + if m != nil { + return m.OnSubcategory + } + return "" +} + +type RetryExitCodeMatcher struct { + Operator ExitCodeOperator `protobuf:"varint,1,opt,name=operator,proto3,enum=api.ExitCodeOperator" json:"operator,omitempty"` + Values []int32 `protobuf:"varint,2,rep,packed,name=values,proto3" json:"values,omitempty"` +} + +func (m *RetryExitCodeMatcher) Reset() { *m = RetryExitCodeMatcher{} } +func (m *RetryExitCodeMatcher) String() string { return proto.CompactTextString(m) } +func (*RetryExitCodeMatcher) ProtoMessage() {} +func (*RetryExitCodeMatcher) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{21} } -func (m *QueueUncordonRequest) XXX_Unmarshal(b []byte) error { +func (m *RetryExitCodeMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueueUncordonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *RetryExitCodeMatcher) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueueUncordonRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_RetryExitCodeMatcher.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1751,42 +1884,48 @@ func (m *QueueUncordonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte return b[:n], nil } } -func (m *QueueUncordonRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueueUncordonRequest.Merge(m, src) +func (m *RetryExitCodeMatcher) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryExitCodeMatcher.Merge(m, src) } -func (m *QueueUncordonRequest) XXX_Size() int { +func (m *RetryExitCodeMatcher) XXX_Size() int { return m.Size() } -func (m *QueueUncordonRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueueUncordonRequest.DiscardUnknown(m) +func (m *RetryExitCodeMatcher) XXX_DiscardUnknown() { + xxx_messageInfo_RetryExitCodeMatcher.DiscardUnknown(m) } -var xxx_messageInfo_QueueUncordonRequest proto.InternalMessageInfo +var xxx_messageInfo_RetryExitCodeMatcher proto.InternalMessageInfo -func (m *QueueUncordonRequest) GetName() string { +func (m *RetryExitCodeMatcher) GetOperator() ExitCodeOperator { if m != nil { - return m.Name + return m.Operator } - return "" + return ExitCodeOperator_EXIT_CODE_OPERATOR_UNSPECIFIED } -//swagger:model -type StreamingQueueGetRequest struct { - Num uint32 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"` +func (m *RetryExitCodeMatcher) GetValues() []int32 { + if m != nil { + return m.Values + } + return nil } -func (m *StreamingQueueGetRequest) Reset() { *m = StreamingQueueGetRequest{} } -func (m *StreamingQueueGetRequest) String() string { return proto.CompactTextString(m) } -func (*StreamingQueueGetRequest) ProtoMessage() {} -func (*StreamingQueueGetRequest) Descriptor() ([]byte, []int) { +type RetryPolicyGetRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *RetryPolicyGetRequest) Reset() { *m = RetryPolicyGetRequest{} } +func (m *RetryPolicyGetRequest) String() string { return proto.CompactTextString(m) } +func (*RetryPolicyGetRequest) ProtoMessage() {} +func (*RetryPolicyGetRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{22} } -func (m *StreamingQueueGetRequest) XXX_Unmarshal(b []byte) error { +func (m *RetryPolicyGetRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *StreamingQueueGetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *RetryPolicyGetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_StreamingQueueGetRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_RetryPolicyGetRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1796,42 +1935,41 @@ func (m *StreamingQueueGetRequest) XXX_Marshal(b []byte, deterministic bool) ([] return b[:n], nil } } -func (m *StreamingQueueGetRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamingQueueGetRequest.Merge(m, src) +func (m *RetryPolicyGetRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryPolicyGetRequest.Merge(m, src) } -func (m *StreamingQueueGetRequest) XXX_Size() int { +func (m *RetryPolicyGetRequest) XXX_Size() int { return m.Size() } -func (m *StreamingQueueGetRequest) XXX_DiscardUnknown() { - xxx_messageInfo_StreamingQueueGetRequest.DiscardUnknown(m) +func (m *RetryPolicyGetRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RetryPolicyGetRequest.DiscardUnknown(m) } -var xxx_messageInfo_StreamingQueueGetRequest proto.InternalMessageInfo +var xxx_messageInfo_RetryPolicyGetRequest proto.InternalMessageInfo -func (m *StreamingQueueGetRequest) GetNum() uint32 { +func (m *RetryPolicyGetRequest) GetName() string { if m != nil { - return m.Num + return m.Name } - return 0 + return "" } -//swagger:model -type QueueDeleteRequest struct { +type RetryPolicyDeleteRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *QueueDeleteRequest) Reset() { *m = QueueDeleteRequest{} } -func (m *QueueDeleteRequest) String() string { return proto.CompactTextString(m) } -func (*QueueDeleteRequest) ProtoMessage() {} -func (*QueueDeleteRequest) Descriptor() ([]byte, []int) { +func (m *RetryPolicyDeleteRequest) Reset() { *m = RetryPolicyDeleteRequest{} } +func (m *RetryPolicyDeleteRequest) String() string { return proto.CompactTextString(m) } +func (*RetryPolicyDeleteRequest) ProtoMessage() {} +func (*RetryPolicyDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{23} } -func (m *QueueDeleteRequest) XXX_Unmarshal(b []byte) error { +func (m *RetryPolicyDeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueueDeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *RetryPolicyDeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueueDeleteRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_RetryPolicyDeleteRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1841,43 +1979,40 @@ func (m *QueueDeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueueDeleteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueueDeleteRequest.Merge(m, src) +func (m *RetryPolicyDeleteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryPolicyDeleteRequest.Merge(m, src) } -func (m *QueueDeleteRequest) XXX_Size() int { +func (m *RetryPolicyDeleteRequest) XXX_Size() int { return m.Size() } -func (m *QueueDeleteRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueueDeleteRequest.DiscardUnknown(m) +func (m *RetryPolicyDeleteRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RetryPolicyDeleteRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueueDeleteRequest proto.InternalMessageInfo +var xxx_messageInfo_RetryPolicyDeleteRequest proto.InternalMessageInfo -func (m *QueueDeleteRequest) GetName() string { +func (m *RetryPolicyDeleteRequest) GetName() string { if m != nil { return m.Name } return "" } -type JobSetInfo struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - QueuedJobs int32 `protobuf:"varint,2,opt,name=queued_jobs,json=queuedJobs,proto3" json:"queuedJobs,omitempty"` - LeasedJobs int32 `protobuf:"varint,3,opt,name=leased_jobs,json=leasedJobs,proto3" json:"leasedJobs,omitempty"` +type RetryPolicyListRequest struct { } -func (m *JobSetInfo) Reset() { *m = JobSetInfo{} } -func (m *JobSetInfo) String() string { return proto.CompactTextString(m) } -func (*JobSetInfo) ProtoMessage() {} -func (*JobSetInfo) Descriptor() ([]byte, []int) { +func (m *RetryPolicyListRequest) Reset() { *m = RetryPolicyListRequest{} } +func (m *RetryPolicyListRequest) String() string { return proto.CompactTextString(m) } +func (*RetryPolicyListRequest) ProtoMessage() {} +func (*RetryPolicyListRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{24} } -func (m *JobSetInfo) XXX_Unmarshal(b []byte) error { +func (m *RetryPolicyListRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *JobSetInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *RetryPolicyListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_JobSetInfo.Marshal(b, m, deterministic) + return xxx_messageInfo_RetryPolicyListRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1887,56 +2022,34 @@ func (m *JobSetInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *JobSetInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_JobSetInfo.Merge(m, src) +func (m *RetryPolicyListRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryPolicyListRequest.Merge(m, src) } -func (m *JobSetInfo) XXX_Size() int { +func (m *RetryPolicyListRequest) XXX_Size() int { return m.Size() } -func (m *JobSetInfo) XXX_DiscardUnknown() { - xxx_messageInfo_JobSetInfo.DiscardUnknown(m) -} - -var xxx_messageInfo_JobSetInfo proto.InternalMessageInfo - -func (m *JobSetInfo) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *JobSetInfo) GetQueuedJobs() int32 { - if m != nil { - return m.QueuedJobs - } - return 0 +func (m *RetryPolicyListRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RetryPolicyListRequest.DiscardUnknown(m) } -func (m *JobSetInfo) GetLeasedJobs() int32 { - if m != nil { - return m.LeasedJobs - } - return 0 -} +var xxx_messageInfo_RetryPolicyListRequest proto.InternalMessageInfo -type QueueUpdateResponse struct { - Queue *Queue `protobuf:"bytes,1,opt,name=queue,proto3" json:"queue,omitempty"` - Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` +type RetryPolicyList struct { + RetryPolicies []*RetryPolicy `protobuf:"bytes,1,rep,name=retry_policies,json=retryPolicies,proto3" json:"retryPolicies,omitempty"` } -func (m *QueueUpdateResponse) Reset() { *m = QueueUpdateResponse{} } -func (m *QueueUpdateResponse) String() string { return proto.CompactTextString(m) } -func (*QueueUpdateResponse) ProtoMessage() {} -func (*QueueUpdateResponse) Descriptor() ([]byte, []int) { +func (m *RetryPolicyList) Reset() { *m = RetryPolicyList{} } +func (m *RetryPolicyList) String() string { return proto.CompactTextString(m) } +func (*RetryPolicyList) ProtoMessage() {} +func (*RetryPolicyList) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{25} } -func (m *QueueUpdateResponse) XXX_Unmarshal(b []byte) error { +func (m *RetryPolicyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueueUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *RetryPolicyList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueueUpdateResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_RetryPolicyList.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1946,48 +2059,42 @@ func (m *QueueUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueueUpdateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueueUpdateResponse.Merge(m, src) +func (m *RetryPolicyList) XXX_Merge(src proto.Message) { + xxx_messageInfo_RetryPolicyList.Merge(m, src) } -func (m *QueueUpdateResponse) XXX_Size() int { +func (m *RetryPolicyList) XXX_Size() int { return m.Size() } -func (m *QueueUpdateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueueUpdateResponse.DiscardUnknown(m) +func (m *RetryPolicyList) XXX_DiscardUnknown() { + xxx_messageInfo_RetryPolicyList.DiscardUnknown(m) } -var xxx_messageInfo_QueueUpdateResponse proto.InternalMessageInfo +var xxx_messageInfo_RetryPolicyList proto.InternalMessageInfo -func (m *QueueUpdateResponse) GetQueue() *Queue { +func (m *RetryPolicyList) GetRetryPolicies() []*RetryPolicy { if m != nil { - return m.Queue + return m.RetryPolicies } return nil } -func (m *QueueUpdateResponse) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -type BatchQueueUpdateResponse struct { - FailedQueues []*QueueUpdateResponse `protobuf:"bytes,1,rep,name=failed_queues,json=failedQueues,proto3" json:"failedQueues,omitempty"` +//swagger:model +type QueueGetRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *BatchQueueUpdateResponse) Reset() { *m = BatchQueueUpdateResponse{} } -func (m *BatchQueueUpdateResponse) String() string { return proto.CompactTextString(m) } -func (*BatchQueueUpdateResponse) ProtoMessage() {} -func (*BatchQueueUpdateResponse) Descriptor() ([]byte, []int) { +func (m *QueueGetRequest) Reset() { *m = QueueGetRequest{} } +func (m *QueueGetRequest) String() string { return proto.CompactTextString(m) } +func (*QueueGetRequest) ProtoMessage() {} +func (*QueueGetRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{26} } -func (m *BatchQueueUpdateResponse) XXX_Unmarshal(b []byte) error { +func (m *QueueGetRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *BatchQueueUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueueGetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_BatchQueueUpdateResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueueGetRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1997,42 +2104,42 @@ func (m *BatchQueueUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([] return b[:n], nil } } -func (m *BatchQueueUpdateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_BatchQueueUpdateResponse.Merge(m, src) +func (m *QueueGetRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueueGetRequest.Merge(m, src) } -func (m *BatchQueueUpdateResponse) XXX_Size() int { +func (m *QueueGetRequest) XXX_Size() int { return m.Size() } -func (m *BatchQueueUpdateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_BatchQueueUpdateResponse.DiscardUnknown(m) +func (m *QueueGetRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueueGetRequest.DiscardUnknown(m) } -var xxx_messageInfo_BatchQueueUpdateResponse proto.InternalMessageInfo +var xxx_messageInfo_QueueGetRequest proto.InternalMessageInfo -func (m *BatchQueueUpdateResponse) GetFailedQueues() []*QueueUpdateResponse { +func (m *QueueGetRequest) GetName() string { if m != nil { - return m.FailedQueues + return m.Name } - return nil + return "" } -type QueueCreateResponse struct { - Queue *Queue `protobuf:"bytes,1,opt,name=queue,proto3" json:"queue,omitempty"` - Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` +//swagger:model +type QueueCordonRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *QueueCreateResponse) Reset() { *m = QueueCreateResponse{} } -func (m *QueueCreateResponse) String() string { return proto.CompactTextString(m) } -func (*QueueCreateResponse) ProtoMessage() {} -func (*QueueCreateResponse) Descriptor() ([]byte, []int) { +func (m *QueueCordonRequest) Reset() { *m = QueueCordonRequest{} } +func (m *QueueCordonRequest) String() string { return proto.CompactTextString(m) } +func (*QueueCordonRequest) ProtoMessage() {} +func (*QueueCordonRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{27} } -func (m *QueueCreateResponse) XXX_Unmarshal(b []byte) error { +func (m *QueueCordonRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueueCreateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueueCordonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueueCreateResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueueCordonRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -2042,48 +2149,42 @@ func (m *QueueCreateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueueCreateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueueCreateResponse.Merge(m, src) +func (m *QueueCordonRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueueCordonRequest.Merge(m, src) } -func (m *QueueCreateResponse) XXX_Size() int { +func (m *QueueCordonRequest) XXX_Size() int { return m.Size() } -func (m *QueueCreateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueueCreateResponse.DiscardUnknown(m) +func (m *QueueCordonRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueueCordonRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueueCreateResponse proto.InternalMessageInfo - -func (m *QueueCreateResponse) GetQueue() *Queue { - if m != nil { - return m.Queue - } - return nil -} +var xxx_messageInfo_QueueCordonRequest proto.InternalMessageInfo -func (m *QueueCreateResponse) GetError() string { +func (m *QueueCordonRequest) GetName() string { if m != nil { - return m.Error + return m.Name } return "" } -type BatchQueueCreateResponse struct { - FailedQueues []*QueueCreateResponse `protobuf:"bytes,1,rep,name=failed_queues,json=failedQueues,proto3" json:"failedQueues,omitempty"` +//swagger:model +type QueueUncordonRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *BatchQueueCreateResponse) Reset() { *m = BatchQueueCreateResponse{} } -func (m *BatchQueueCreateResponse) String() string { return proto.CompactTextString(m) } -func (*BatchQueueCreateResponse) ProtoMessage() {} -func (*BatchQueueCreateResponse) Descriptor() ([]byte, []int) { +func (m *QueueUncordonRequest) Reset() { *m = QueueUncordonRequest{} } +func (m *QueueUncordonRequest) String() string { return proto.CompactTextString(m) } +func (*QueueUncordonRequest) ProtoMessage() {} +func (*QueueUncordonRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{28} } -func (m *BatchQueueCreateResponse) XXX_Unmarshal(b []byte) error { +func (m *QueueUncordonRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *BatchQueueCreateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueueUncordonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_BatchQueueCreateResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueueUncordonRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -2093,41 +2194,42 @@ func (m *BatchQueueCreateResponse) XXX_Marshal(b []byte, deterministic bool) ([] return b[:n], nil } } -func (m *BatchQueueCreateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_BatchQueueCreateResponse.Merge(m, src) +func (m *QueueUncordonRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueueUncordonRequest.Merge(m, src) } -func (m *BatchQueueCreateResponse) XXX_Size() int { +func (m *QueueUncordonRequest) XXX_Size() int { return m.Size() } -func (m *BatchQueueCreateResponse) XXX_DiscardUnknown() { - xxx_messageInfo_BatchQueueCreateResponse.DiscardUnknown(m) +func (m *QueueUncordonRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueueUncordonRequest.DiscardUnknown(m) } -var xxx_messageInfo_BatchQueueCreateResponse proto.InternalMessageInfo +var xxx_messageInfo_QueueUncordonRequest proto.InternalMessageInfo -func (m *BatchQueueCreateResponse) GetFailedQueues() []*QueueCreateResponse { +func (m *QueueUncordonRequest) GetName() string { if m != nil { - return m.FailedQueues + return m.Name } - return nil + return "" } -// Indicates the end of streams -type EndMarker struct { +//swagger:model +type StreamingQueueGetRequest struct { + Num uint32 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"` } -func (m *EndMarker) Reset() { *m = EndMarker{} } -func (m *EndMarker) String() string { return proto.CompactTextString(m) } -func (*EndMarker) ProtoMessage() {} -func (*EndMarker) Descriptor() ([]byte, []int) { +func (m *StreamingQueueGetRequest) Reset() { *m = StreamingQueueGetRequest{} } +func (m *StreamingQueueGetRequest) String() string { return proto.CompactTextString(m) } +func (*StreamingQueueGetRequest) ProtoMessage() {} +func (*StreamingQueueGetRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{29} } -func (m *EndMarker) XXX_Unmarshal(b []byte) error { +func (m *StreamingQueueGetRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *EndMarker) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *StreamingQueueGetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_EndMarker.Marshal(b, m, deterministic) + return xxx_messageInfo_StreamingQueueGetRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -2137,37 +2239,42 @@ func (m *EndMarker) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *EndMarker) XXX_Merge(src proto.Message) { - xxx_messageInfo_EndMarker.Merge(m, src) +func (m *StreamingQueueGetRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamingQueueGetRequest.Merge(m, src) } -func (m *EndMarker) XXX_Size() int { +func (m *StreamingQueueGetRequest) XXX_Size() int { return m.Size() } -func (m *EndMarker) XXX_DiscardUnknown() { - xxx_messageInfo_EndMarker.DiscardUnknown(m) +func (m *StreamingQueueGetRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StreamingQueueGetRequest.DiscardUnknown(m) } -var xxx_messageInfo_EndMarker proto.InternalMessageInfo +var xxx_messageInfo_StreamingQueueGetRequest proto.InternalMessageInfo -type StreamingQueueMessage struct { - // Types that are valid to be assigned to Event: - // *StreamingQueueMessage_Queue - // *StreamingQueueMessage_End - Event isStreamingQueueMessage_Event `protobuf_oneof:"event"` +func (m *StreamingQueueGetRequest) GetNum() uint32 { + if m != nil { + return m.Num + } + return 0 } -func (m *StreamingQueueMessage) Reset() { *m = StreamingQueueMessage{} } -func (m *StreamingQueueMessage) String() string { return proto.CompactTextString(m) } -func (*StreamingQueueMessage) ProtoMessage() {} -func (*StreamingQueueMessage) Descriptor() ([]byte, []int) { +//swagger:model +type QueueDeleteRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *QueueDeleteRequest) Reset() { *m = QueueDeleteRequest{} } +func (m *QueueDeleteRequest) String() string { return proto.CompactTextString(m) } +func (*QueueDeleteRequest) ProtoMessage() {} +func (*QueueDeleteRequest) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{30} } -func (m *StreamingQueueMessage) XXX_Unmarshal(b []byte) error { +func (m *QueueDeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *StreamingQueueMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueueDeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_StreamingQueueMessage.Marshal(b, m, deterministic) + return xxx_messageInfo_QueueDeleteRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -2177,82 +2284,43 @@ func (m *StreamingQueueMessage) XXX_Marshal(b []byte, deterministic bool) ([]byt return b[:n], nil } } -func (m *StreamingQueueMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamingQueueMessage.Merge(m, src) +func (m *QueueDeleteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueueDeleteRequest.Merge(m, src) } -func (m *StreamingQueueMessage) XXX_Size() int { +func (m *QueueDeleteRequest) XXX_Size() int { return m.Size() } -func (m *StreamingQueueMessage) XXX_DiscardUnknown() { - xxx_messageInfo_StreamingQueueMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_StreamingQueueMessage proto.InternalMessageInfo - -type isStreamingQueueMessage_Event interface { - isStreamingQueueMessage_Event() - MarshalTo([]byte) (int, error) - Size() int -} - -type StreamingQueueMessage_Queue struct { - Queue *Queue `protobuf:"bytes,1,opt,name=queue,proto3,oneof" json:"queue,omitempty"` -} -type StreamingQueueMessage_End struct { - End *EndMarker `protobuf:"bytes,2,opt,name=end,proto3,oneof" json:"end,omitempty"` +func (m *QueueDeleteRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueueDeleteRequest.DiscardUnknown(m) } -func (*StreamingQueueMessage_Queue) isStreamingQueueMessage_Event() {} -func (*StreamingQueueMessage_End) isStreamingQueueMessage_Event() {} +var xxx_messageInfo_QueueDeleteRequest proto.InternalMessageInfo -func (m *StreamingQueueMessage) GetEvent() isStreamingQueueMessage_Event { +func (m *QueueDeleteRequest) GetName() string { if m != nil { - return m.Event - } - return nil -} - -func (m *StreamingQueueMessage) GetQueue() *Queue { - if x, ok := m.GetEvent().(*StreamingQueueMessage_Queue); ok { - return x.Queue - } - return nil -} - -func (m *StreamingQueueMessage) GetEnd() *EndMarker { - if x, ok := m.GetEvent().(*StreamingQueueMessage_End); ok { - return x.End - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*StreamingQueueMessage) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*StreamingQueueMessage_Queue)(nil), - (*StreamingQueueMessage_End)(nil), + return m.Name } + return "" } -type QueuePreemptRequest struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - PriorityClasses []string `protobuf:"bytes,2,rep,name=priorityClasses,proto3" json:"priorityClasses,omitempty"` - // If empty, jobs on all pools will be preempted - Pools []string `protobuf:"bytes,3,rep,name=pools,proto3" json:"pools,omitempty"` +type JobSetInfo struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + QueuedJobs int32 `protobuf:"varint,2,opt,name=queued_jobs,json=queuedJobs,proto3" json:"queuedJobs,omitempty"` + LeasedJobs int32 `protobuf:"varint,3,opt,name=leased_jobs,json=leasedJobs,proto3" json:"leasedJobs,omitempty"` } -func (m *QueuePreemptRequest) Reset() { *m = QueuePreemptRequest{} } -func (m *QueuePreemptRequest) String() string { return proto.CompactTextString(m) } -func (*QueuePreemptRequest) ProtoMessage() {} -func (*QueuePreemptRequest) Descriptor() ([]byte, []int) { +func (m *JobSetInfo) Reset() { *m = JobSetInfo{} } +func (m *JobSetInfo) String() string { return proto.CompactTextString(m) } +func (*JobSetInfo) ProtoMessage() {} +func (*JobSetInfo) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{31} } -func (m *QueuePreemptRequest) XXX_Unmarshal(b []byte) error { +func (m *JobSetInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueuePreemptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *JobSetInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueuePreemptRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_JobSetInfo.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -2262,60 +2330,56 @@ func (m *QueuePreemptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueuePreemptRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueuePreemptRequest.Merge(m, src) +func (m *JobSetInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_JobSetInfo.Merge(m, src) } -func (m *QueuePreemptRequest) XXX_Size() int { +func (m *JobSetInfo) XXX_Size() int { return m.Size() } -func (m *QueuePreemptRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueuePreemptRequest.DiscardUnknown(m) +func (m *JobSetInfo) XXX_DiscardUnknown() { + xxx_messageInfo_JobSetInfo.DiscardUnknown(m) } -var xxx_messageInfo_QueuePreemptRequest proto.InternalMessageInfo +var xxx_messageInfo_JobSetInfo proto.InternalMessageInfo -func (m *QueuePreemptRequest) GetName() string { +func (m *JobSetInfo) GetName() string { if m != nil { return m.Name } return "" } -func (m *QueuePreemptRequest) GetPriorityClasses() []string { +func (m *JobSetInfo) GetQueuedJobs() int32 { if m != nil { - return m.PriorityClasses + return m.QueuedJobs } - return nil + return 0 } -func (m *QueuePreemptRequest) GetPools() []string { +func (m *JobSetInfo) GetLeasedJobs() int32 { if m != nil { - return m.Pools + return m.LeasedJobs } - return nil + return 0 } -type QueueCancelRequest struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - PriorityClasses []string `protobuf:"bytes,2,rep,name=priorityClasses,proto3" json:"priorityClasses,omitempty"` - // In practice jobs are only cancellable from non-terminal states - JobStates []JobState `protobuf:"varint,3,rep,packed,name=jobStates,proto3,enum=api.JobState" json:"jobStates,omitempty"` - // If empty, jobs on all pools will be cancelled - Pools []string `protobuf:"bytes,4,rep,name=pools,proto3" json:"pools,omitempty"` +type QueueUpdateResponse struct { + Queue *Queue `protobuf:"bytes,1,opt,name=queue,proto3" json:"queue,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` } -func (m *QueueCancelRequest) Reset() { *m = QueueCancelRequest{} } -func (m *QueueCancelRequest) String() string { return proto.CompactTextString(m) } -func (*QueueCancelRequest) ProtoMessage() {} -func (*QueueCancelRequest) Descriptor() ([]byte, []int) { +func (m *QueueUpdateResponse) Reset() { *m = QueueUpdateResponse{} } +func (m *QueueUpdateResponse) String() string { return proto.CompactTextString(m) } +func (*QueueUpdateResponse) ProtoMessage() {} +func (*QueueUpdateResponse) Descriptor() ([]byte, []int) { return fileDescriptor_e998bacb27df16c1, []int{32} } -func (m *QueueCancelRequest) XXX_Unmarshal(b []byte) error { +func (m *QueueUpdateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueueCancelRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueueUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueueCancelRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueueUpdateResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -2325,396 +2389,823 @@ func (m *QueueCancelRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueueCancelRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueueCancelRequest.Merge(m, src) +func (m *QueueUpdateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueueUpdateResponse.Merge(m, src) } -func (m *QueueCancelRequest) XXX_Size() int { +func (m *QueueUpdateResponse) XXX_Size() int { return m.Size() } -func (m *QueueCancelRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueueCancelRequest.DiscardUnknown(m) +func (m *QueueUpdateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueueUpdateResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueueCancelRequest proto.InternalMessageInfo +var xxx_messageInfo_QueueUpdateResponse proto.InternalMessageInfo -func (m *QueueCancelRequest) GetName() string { +func (m *QueueUpdateResponse) GetQueue() *Queue { if m != nil { - return m.Name + return m.Queue } - return "" + return nil } -func (m *QueueCancelRequest) GetPriorityClasses() []string { +func (m *QueueUpdateResponse) GetError() string { if m != nil { - return m.PriorityClasses + return m.Error } - return nil + return "" } -func (m *QueueCancelRequest) GetJobStates() []JobState { - if m != nil { - return m.JobStates - } - return nil +type BatchQueueUpdateResponse struct { + FailedQueues []*QueueUpdateResponse `protobuf:"bytes,1,rep,name=failed_queues,json=failedQueues,proto3" json:"failedQueues,omitempty"` } -func (m *QueueCancelRequest) GetPools() []string { - if m != nil { - return m.Pools +func (m *BatchQueueUpdateResponse) Reset() { *m = BatchQueueUpdateResponse{} } +func (m *BatchQueueUpdateResponse) String() string { return proto.CompactTextString(m) } +func (*BatchQueueUpdateResponse) ProtoMessage() {} +func (*BatchQueueUpdateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{33} +} +func (m *BatchQueueUpdateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BatchQueueUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BatchQueueUpdateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return nil } - -func init() { - proto.RegisterEnum("api.IngressType", IngressType_name, IngressType_value) - proto.RegisterEnum("api.ServiceType", ServiceType_name, ServiceType_value) - proto.RegisterEnum("api.JobState", JobState_name, JobState_value) - proto.RegisterType((*JobSubmitRequestItem)(nil), "api.JobSubmitRequestItem") - proto.RegisterMapType((map[string]string)(nil), "api.JobSubmitRequestItem.AnnotationsEntry") - proto.RegisterMapType((map[string]string)(nil), "api.JobSubmitRequestItem.LabelsEntry") - proto.RegisterMapType((map[string]string)(nil), "api.JobSubmitRequestItem.RequiredNodeLabelsEntry") - proto.RegisterType((*IngressConfig)(nil), "api.IngressConfig") - proto.RegisterMapType((map[string]string)(nil), "api.IngressConfig.AnnotationsEntry") - proto.RegisterType((*ServiceConfig)(nil), "api.ServiceConfig") - proto.RegisterType((*JobSubmitRequest)(nil), "api.JobSubmitRequest") - proto.RegisterType((*JobPreemptRequest)(nil), "api.JobPreemptRequest") - proto.RegisterType((*JobCancelRequest)(nil), "api.JobCancelRequest") - proto.RegisterType((*JobSetCancelRequest)(nil), "api.JobSetCancelRequest") - proto.RegisterType((*JobSetFilter)(nil), "api.JobSetFilter") - proto.RegisterType((*Job)(nil), "api.Job") - proto.RegisterMapType((map[string]string)(nil), "api.Job.AnnotationsEntry") - proto.RegisterMapType((map[string]string)(nil), "api.Job.LabelsEntry") - proto.RegisterMapType((map[string]string)(nil), "api.Job.RequiredNodeLabelsEntry") - proto.RegisterType((*JobReprioritizeRequest)(nil), "api.JobReprioritizeRequest") - proto.RegisterType((*JobReprioritizeResponse)(nil), "api.JobReprioritizeResponse") - proto.RegisterMapType((map[string]string)(nil), "api.JobReprioritizeResponse.ReprioritizationResultsEntry") - proto.RegisterType((*JobSubmitResponseItem)(nil), "api.JobSubmitResponseItem") - proto.RegisterType((*JobSubmitResponse)(nil), "api.JobSubmitResponse") - proto.RegisterType((*Queue)(nil), "api.Queue") - proto.RegisterMapType((map[string]string)(nil), "api.Queue.LabelsEntry") - proto.RegisterMapType((map[string]*PriorityClassResourceLimits)(nil), "api.Queue.ResourceLimitsByPriorityClassNameEntry") - proto.RegisterMapType((map[string]float64)(nil), "api.Queue.ResourceLimitsEntry") - proto.RegisterType((*Queue_Permissions)(nil), "api.Queue.Permissions") - proto.RegisterType((*Queue_Permissions_Subject)(nil), "api.Queue.Permissions.Subject") - proto.RegisterType((*PriorityClassResourceLimits)(nil), "api.PriorityClassResourceLimits") - proto.RegisterMapType((map[string]*PriorityClassPoolResourceLimits)(nil), "api.PriorityClassResourceLimits.MaximumResourceFractionByPoolEntry") - proto.RegisterMapType((map[string]float64)(nil), "api.PriorityClassResourceLimits.MaximumResourceFractionEntry") - proto.RegisterType((*PriorityClassPoolResourceLimits)(nil), "api.PriorityClassPoolResourceLimits") - proto.RegisterMapType((map[string]float64)(nil), "api.PriorityClassPoolResourceLimits.MaximumResourceFractionEntry") - proto.RegisterType((*QueueList)(nil), "api.QueueList") - proto.RegisterType((*CancellationResult)(nil), "api.CancellationResult") - proto.RegisterType((*PreemptionResult)(nil), "api.PreemptionResult") - proto.RegisterMapType((map[string]string)(nil), "api.PreemptionResult.PreemptionResultsEntry") - proto.RegisterType((*QueueGetRequest)(nil), "api.QueueGetRequest") - proto.RegisterType((*QueueCordonRequest)(nil), "api.QueueCordonRequest") - proto.RegisterType((*QueueUncordonRequest)(nil), "api.QueueUncordonRequest") - proto.RegisterType((*StreamingQueueGetRequest)(nil), "api.StreamingQueueGetRequest") - proto.RegisterType((*QueueDeleteRequest)(nil), "api.QueueDeleteRequest") - proto.RegisterType((*JobSetInfo)(nil), "api.JobSetInfo") - proto.RegisterType((*QueueUpdateResponse)(nil), "api.QueueUpdateResponse") - proto.RegisterType((*BatchQueueUpdateResponse)(nil), "api.BatchQueueUpdateResponse") - proto.RegisterType((*QueueCreateResponse)(nil), "api.QueueCreateResponse") - proto.RegisterType((*BatchQueueCreateResponse)(nil), "api.BatchQueueCreateResponse") - proto.RegisterType((*EndMarker)(nil), "api.EndMarker") - proto.RegisterType((*StreamingQueueMessage)(nil), "api.StreamingQueueMessage") - proto.RegisterType((*QueuePreemptRequest)(nil), "api.QueuePreemptRequest") - proto.RegisterType((*QueueCancelRequest)(nil), "api.QueueCancelRequest") +func (m *BatchQueueUpdateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BatchQueueUpdateResponse.Merge(m, src) } - -func init() { proto.RegisterFile("pkg/api/submit.proto", fileDescriptor_e998bacb27df16c1) } - -var fileDescriptor_e998bacb27df16c1 = []byte{ - // 3241 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3a, 0xcb, 0x6f, 0x1b, 0xc7, - 0xf9, 0x5a, 0x51, 0x2f, 0x7e, 0x14, 0x25, 0x6a, 0x2c, 0xc9, 0x2b, 0xda, 0x11, 0xe5, 0x4d, 0xe2, - 0xc8, 0x8e, 0x7f, 0x54, 0xac, 0xfc, 0x82, 0xda, 0x6e, 0x5a, 0x57, 0xa4, 0x28, 0x5b, 0xb2, 0x2d, - 0x2b, 0x92, 0x95, 0x47, 0x51, 0x94, 0x5d, 0x72, 0x47, 0xd4, 0x4a, 0xcb, 0xdd, 0xcd, 0xee, 0x52, - 0x8e, 0xda, 0xe6, 0x52, 0x14, 0x08, 0xd0, 0x53, 0xd0, 0x1e, 0x5b, 0xb4, 0x3d, 0xf4, 0x50, 0xa4, - 0xa7, 0x1e, 0x7a, 0x29, 0xfa, 0x07, 0x14, 0x3d, 0xa5, 0xe8, 0xa5, 0xbd, 0x10, 0x45, 0xd2, 0x07, - 0x40, 0xa0, 0x87, 0x5e, 0x7a, 0x2a, 0x8a, 0x62, 0x1e, 0xbb, 0x3b, 0xcb, 0x37, 0x6d, 0x2b, 0xb9, - 0xf4, 0xc6, 0xfd, 0xe6, 0x7b, 0xcf, 0x37, 0xdf, 0x63, 0x86, 0x30, 0x6b, 0x1f, 0x57, 0x56, 0x54, - 0x5b, 0x5f, 0x71, 0x6b, 0xa5, 0xaa, 0xee, 0x65, 0x6d, 0xc7, 0xf2, 0x2c, 0x14, 0x53, 0x6d, 0x3d, - 0x7d, 0xa1, 0x62, 0x59, 0x15, 0x03, 0xaf, 0x50, 0x50, 0xa9, 0x76, 0xb0, 0x82, 0xab, 0xb6, 0x77, - 0xca, 0x30, 0xd2, 0x99, 0xe6, 0x45, 0x4f, 0xaf, 0x62, 0xd7, 0x53, 0xab, 0x36, 0x47, 0x50, 0x8e, - 0x6f, 0xb8, 0x59, 0xdd, 0xa2, 0xbc, 0xcb, 0x96, 0x83, 0x57, 0x4e, 0xae, 0xaf, 0x54, 0xb0, 0x89, - 0x1d, 0xd5, 0xc3, 0x1a, 0xc7, 0x59, 0x16, 0x70, 0x4c, 0xec, 0x3d, 0xb6, 0x9c, 0x63, 0xdd, 0xac, - 0xb4, 0xc3, 0xbc, 0xc8, 0xc5, 0x11, 0x4c, 0xd5, 0x34, 0x2d, 0x4f, 0xf5, 0x74, 0xcb, 0x74, 0xf9, - 0x6a, 0x60, 0xc4, 0x21, 0x56, 0x0d, 0xef, 0x90, 0x41, 0x95, 0x7f, 0xc4, 0x61, 0x76, 0xcb, 0x2a, - 0xed, 0x51, 0xc3, 0x76, 0xf1, 0xbb, 0x35, 0xec, 0x7a, 0x9b, 0x1e, 0xae, 0xa2, 0x55, 0x98, 0xb0, - 0x1d, 0xdd, 0x72, 0x74, 0xef, 0x54, 0x96, 0x96, 0xa4, 0x65, 0x29, 0x37, 0xdf, 0xa8, 0x67, 0x90, - 0x0f, 0xbb, 0x66, 0x55, 0x75, 0x8f, 0xda, 0xba, 0x1b, 0xe0, 0xa1, 0xd7, 0x20, 0x6e, 0xaa, 0x55, - 0xec, 0xda, 0x6a, 0x19, 0xcb, 0xb1, 0x25, 0x69, 0x39, 0x9e, 0x3b, 0xdf, 0xa8, 0x67, 0xce, 0x05, - 0x40, 0x81, 0x2a, 0xc4, 0x44, 0xaf, 0x42, 0xbc, 0x6c, 0xe8, 0xd8, 0xf4, 0x8a, 0xba, 0x26, 0x4f, - 0x50, 0x32, 0x2a, 0x8b, 0x01, 0x37, 0x35, 0x51, 0x96, 0x0f, 0x43, 0x7b, 0x30, 0x66, 0xa8, 0x25, - 0x6c, 0xb8, 0xf2, 0xc8, 0x52, 0x6c, 0x39, 0xb1, 0xfa, 0x62, 0x56, 0xb5, 0xf5, 0x6c, 0x3b, 0x53, - 0xb2, 0xf7, 0x29, 0x5e, 0xc1, 0xf4, 0x9c, 0xd3, 0xdc, 0x6c, 0xa3, 0x9e, 0x49, 0x31, 0x42, 0x81, - 0x2d, 0x67, 0x85, 0x2a, 0x90, 0x10, 0x1c, 0x27, 0x8f, 0x52, 0xce, 0x57, 0x3b, 0x73, 0x5e, 0x0b, - 0x91, 0x19, 0xfb, 0x85, 0x46, 0x3d, 0x33, 0x27, 0xb0, 0x10, 0x64, 0x88, 0x9c, 0xd1, 0x07, 0x12, - 0xcc, 0x3a, 0xf8, 0xdd, 0x9a, 0xee, 0x60, 0xad, 0x68, 0x5a, 0x1a, 0x2e, 0x72, 0x63, 0xc6, 0xa8, - 0xc8, 0xeb, 0x9d, 0x45, 0xee, 0x72, 0xaa, 0x6d, 0x4b, 0xc3, 0xa2, 0x61, 0x4a, 0xa3, 0x9e, 0xb9, - 0xe8, 0xb4, 0x2c, 0x86, 0x0a, 0xc8, 0xd2, 0x2e, 0x6a, 0x5d, 0x47, 0x0f, 0x61, 0xc2, 0xb6, 0xb4, - 0xa2, 0x6b, 0xe3, 0xb2, 0x3c, 0xbc, 0x24, 0x2d, 0x27, 0x56, 0x2f, 0x64, 0x59, 0xc4, 0x51, 0x1d, - 0x48, 0x54, 0x66, 0x4f, 0xae, 0x67, 0x77, 0x2c, 0x6d, 0xcf, 0xc6, 0x65, 0xba, 0x9f, 0x33, 0x36, - 0xfb, 0x88, 0xf0, 0x1e, 0xe7, 0x40, 0xb4, 0x03, 0x71, 0x9f, 0xa1, 0x2b, 0x8f, 0x53, 0x73, 0xba, - 0x72, 0x64, 0x61, 0xc5, 0x3e, 0xdc, 0x48, 0x58, 0x71, 0x18, 0xca, 0xc3, 0xb8, 0x6e, 0x56, 0x1c, - 0xec, 0xba, 0x72, 0x9c, 0xf2, 0x43, 0x94, 0xd1, 0x26, 0x83, 0xe5, 0x2d, 0xf3, 0x40, 0xaf, 0xe4, - 0xe6, 0x88, 0x62, 0x1c, 0x4d, 0xe0, 0xe2, 0x53, 0xa2, 0x0d, 0x98, 0x70, 0xb1, 0x73, 0xa2, 0x97, - 0xb1, 0x2b, 0x83, 0xc0, 0x65, 0x8f, 0x01, 0x39, 0x17, 0xaa, 0x8c, 0x8f, 0x27, 0x2a, 0xe3, 0xc3, - 0x48, 0x8c, 0xbb, 0xe5, 0x43, 0xac, 0xd5, 0x0c, 0xec, 0xc8, 0x89, 0x30, 0xc6, 0x03, 0xa0, 0x18, - 0xe3, 0x01, 0x10, 0x6d, 0x40, 0x0a, 0xbf, 0xe7, 0x61, 0xc7, 0x54, 0x8d, 0xe2, 0x91, 0x55, 0x2a, - 0xd6, 0x1c, 0x5d, 0x4e, 0x52, 0xea, 0x8b, 0x8d, 0x7a, 0x46, 0xf6, 0xd7, 0xb6, 0xac, 0xd2, 0xbe, - 0xa3, 0x0b, 0x2c, 0xa6, 0xa2, 0x2b, 0x69, 0x15, 0x12, 0xc2, 0xae, 0xa3, 0xe7, 0x21, 0x76, 0x8c, - 0xd9, 0x01, 0x8d, 0xe7, 0x66, 0x1a, 0xf5, 0x4c, 0xf2, 0x18, 0x8b, 0x67, 0x93, 0xac, 0xa2, 0x2b, - 0x30, 0x7a, 0xa2, 0x1a, 0x35, 0x4c, 0xf7, 0x37, 0x9e, 0x3b, 0xd7, 0xa8, 0x67, 0xa6, 0x29, 0x40, - 0x40, 0x64, 0x18, 0xb7, 0x86, 0x6f, 0x48, 0xe9, 0x03, 0x48, 0x35, 0xc7, 0xf5, 0x99, 0xc8, 0xa9, - 0xc2, 0xf9, 0x0e, 0xc1, 0x7c, 0x16, 0xe2, 0xb6, 0x46, 0x26, 0x26, 0x53, 0x49, 0xe5, 0x9f, 0x31, - 0x48, 0x46, 0x02, 0x07, 0xdd, 0x82, 0x11, 0xef, 0xd4, 0xc6, 0x54, 0xd8, 0xd4, 0x6a, 0x4a, 0x0c, - 0xad, 0x47, 0xa7, 0x36, 0xa6, 0x19, 0x63, 0x8a, 0x60, 0x44, 0xc2, 0x9d, 0xd2, 0x10, 0x15, 0x6c, - 0xcb, 0xf1, 0x5c, 0x79, 0x78, 0x29, 0xb6, 0x9c, 0x64, 0x2a, 0x50, 0x80, 0xa8, 0x02, 0x05, 0xa0, - 0x6f, 0x44, 0x53, 0x4b, 0x8c, 0x86, 0xe0, 0xf3, 0xad, 0x81, 0xfc, 0xe4, 0x39, 0xe5, 0x26, 0x24, - 0x3c, 0xc3, 0x2d, 0x62, 0x53, 0x2d, 0x19, 0x58, 0x93, 0x47, 0x96, 0xa4, 0xe5, 0x89, 0x9c, 0xdc, - 0xa8, 0x67, 0x66, 0x3d, 0xe2, 0x57, 0x0a, 0x15, 0x68, 0x21, 0x84, 0xd2, 0x0c, 0x8c, 0x1d, 0xaf, - 0x48, 0x72, 0xb2, 0x3c, 0x2a, 0x64, 0x60, 0xec, 0x78, 0xdb, 0x6a, 0x15, 0x47, 0x32, 0x30, 0x87, - 0xa1, 0xdb, 0x90, 0xac, 0xb9, 0xb8, 0x58, 0x36, 0x6a, 0xae, 0x87, 0x9d, 0xcd, 0x1d, 0x79, 0x8c, - 0x4a, 0x4c, 0x37, 0xea, 0x99, 0xf9, 0x9a, 0x8b, 0xf3, 0x3e, 0x5c, 0x20, 0x9e, 0x14, 0xe1, 0x9f, - 0x55, 0xa0, 0x29, 0x3f, 0x92, 0x20, 0x19, 0x39, 0xe6, 0xe8, 0x46, 0x9b, 0x3d, 0xe7, 0x18, 0x74, - 0xcf, 0x51, 0xeb, 0x9e, 0x0f, 0xbe, 0xe3, 0x97, 0x61, 0x84, 0xfa, 0x93, 0x15, 0x42, 0xca, 0xd2, - 0x8c, 0xfa, 0x92, 0xae, 0x2b, 0x7f, 0x92, 0x20, 0xd5, 0x9c, 0xea, 0x89, 0x9c, 0x77, 0x6b, 0xb8, - 0x86, 0xb9, 0x27, 0xa8, 0x1c, 0x0a, 0x10, 0xe5, 0x50, 0x00, 0xfa, 0x7f, 0x00, 0x92, 0x51, 0x5c, - 0x4c, 0xeb, 0xe7, 0x70, 0xb8, 0x7b, 0x47, 0x56, 0x69, 0x0f, 0x37, 0xd5, 0x4f, 0x1f, 0x86, 0x34, - 0x98, 0x21, 0x54, 0x0e, 0x93, 0x57, 0x24, 0x08, 0x7e, 0x54, 0x2e, 0x74, 0xac, 0x3e, 0xb9, 0xe7, - 0x1a, 0xf5, 0xcc, 0xc2, 0x91, 0x55, 0x12, 0x60, 0xa2, 0xe5, 0xd3, 0x4d, 0x4b, 0xca, 0xef, 0x25, - 0x98, 0xd9, 0xb2, 0x4a, 0x3b, 0x0e, 0x26, 0x08, 0x9f, 0x99, 0x71, 0xff, 0x07, 0xe3, 0x84, 0x4a, - 0xd7, 0x98, 0x49, 0x71, 0x56, 0xf6, 0x8f, 0xac, 0xd2, 0xa6, 0x16, 0x29, 0xfb, 0x0c, 0x82, 0xae, - 0xc1, 0x98, 0x83, 0x55, 0xd7, 0x32, 0xe9, 0xa1, 0xe1, 0xd8, 0x0c, 0x22, 0x62, 0x33, 0x88, 0xf2, - 0x6f, 0xb6, 0x5f, 0x79, 0xd5, 0x2c, 0x63, 0xc3, 0x37, 0xe9, 0x2a, 0x8c, 0x31, 0x89, 0xa2, 0x4d, - 0x94, 0xbd, 0x68, 0x13, 0x05, 0x3c, 0xa1, 0x4d, 0x81, 0xd3, 0x62, 0x3d, 0x9d, 0x26, 0x98, 0x3f, - 0x32, 0x90, 0xf9, 0xa3, 0x7d, 0x98, 0xff, 0x57, 0x09, 0xce, 0x6d, 0x51, 0xa5, 0xa2, 0x1e, 0x88, - 0x5a, 0x25, 0x0d, 0x6a, 0xd5, 0x70, 0x4f, 0xab, 0x6e, 0xc3, 0xd8, 0x81, 0x6e, 0x78, 0xd8, 0xa1, - 0x1e, 0x48, 0xac, 0xce, 0x04, 0x61, 0x8a, 0xbd, 0x0d, 0xba, 0xc0, 0x34, 0x67, 0x48, 0xa2, 0xe6, - 0x0c, 0x32, 0xe0, 0x36, 0xdf, 0x83, 0x49, 0x91, 0x37, 0xfa, 0x22, 0x8c, 0xb9, 0x9e, 0xea, 0x61, - 0x57, 0x96, 0x96, 0x62, 0xcb, 0x53, 0xab, 0xc9, 0x40, 0x3c, 0x81, 0x32, 0x66, 0x0c, 0x41, 0x64, - 0xc6, 0x20, 0xca, 0xcf, 0xa7, 0x21, 0xb6, 0x65, 0x95, 0xd0, 0x12, 0x0c, 0x07, 0xce, 0x49, 0x35, - 0xea, 0x99, 0x49, 0x5d, 0x74, 0xcb, 0xb0, 0xae, 0x45, 0x9b, 0xe1, 0x64, 0x9f, 0xcd, 0xf0, 0x99, - 0x47, 0x54, 0xa4, 0xb3, 0x1f, 0xef, 0xbb, 0xb3, 0xcf, 0x05, 0x4d, 0x3a, 0x6b, 0xdc, 0x66, 0x7d, - 0x9f, 0x0d, 0xd0, 0x93, 0xbf, 0x19, 0x2d, 0x9c, 0x10, 0x4d, 0x51, 0x4f, 0x5e, 0x2e, 0x4f, 0x3a, - 0x74, 0xe0, 0x09, 0x2a, 0x60, 0x29, 0x10, 0xf0, 0xac, 0x1b, 0xee, 0x2b, 0x30, 0x6a, 0x3d, 0x36, - 0xb1, 0xc3, 0x27, 0x1d, 0xea, 0x75, 0x0a, 0x10, 0xbd, 0x4e, 0x01, 0x08, 0xc3, 0x05, 0xea, 0xfe, - 0x22, 0xfd, 0x74, 0x0f, 0x75, 0xbb, 0x58, 0x73, 0xb1, 0x53, 0xac, 0x38, 0x56, 0xcd, 0x76, 0xe5, - 0x69, 0x7a, 0xb6, 0x2f, 0x37, 0xea, 0x19, 0x85, 0xa2, 0x3d, 0xf4, 0xb1, 0xf6, 0x5d, 0xec, 0xdc, - 0xa1, 0x38, 0x02, 0x4f, 0xb9, 0x13, 0x0e, 0xfa, 0xae, 0x04, 0x97, 0xcb, 0x56, 0xd5, 0x26, 0x4d, - 0x08, 0xd6, 0x8a, 0xdd, 0x44, 0x9e, 0x5b, 0x92, 0x96, 0x27, 0x73, 0xaf, 0x34, 0xea, 0x99, 0x6b, - 0x21, 0xc5, 0x1b, 0xbd, 0x85, 0x2b, 0xbd, 0xb1, 0x23, 0x13, 0xe7, 0x48, 0x9f, 0x13, 0xa7, 0x38, - 0xbd, 0x8c, 0x3e, 0xf3, 0xe9, 0x65, 0xf2, 0x59, 0x4c, 0x2f, 0x3f, 0x95, 0x60, 0x89, 0xcf, 0x01, - 0xba, 0x59, 0x29, 0x3a, 0xd8, 0xb5, 0x6a, 0x4e, 0x19, 0x17, 0x79, 0x68, 0x54, 0xb1, 0xe9, 0xb9, - 0xf2, 0x1c, 0xd5, 0x7d, 0xb9, 0x9d, 0xa4, 0x5d, 0x4e, 0xb0, 0x2b, 0xe0, 0xe7, 0xae, 0x35, 0xea, - 0x99, 0xe5, 0x90, 0x6b, 0x3b, 0x1c, 0x41, 0x99, 0xc5, 0xee, 0x98, 0xe8, 0x1e, 0x8c, 0x97, 0x1d, - 0xac, 0x7a, 0x58, 0xa3, 0x3d, 0x5c, 0x62, 0x35, 0x9d, 0x65, 0x57, 0x09, 0x59, 0xff, 0xe6, 0x22, - 0xfb, 0xc8, 0xbf, 0xb9, 0x60, 0x83, 0x16, 0x47, 0x17, 0x07, 0x2d, 0x0e, 0x12, 0xa7, 0xb5, 0xa9, - 0x67, 0x32, 0xad, 0xa5, 0x9e, 0x62, 0x5a, 0xfb, 0x1a, 0x24, 0x8e, 0x6f, 0xb8, 0x45, 0x5f, 0xa1, - 0x19, 0xca, 0xea, 0x92, 0xe8, 0xe6, 0xf0, 0x4a, 0x85, 0x38, 0x9b, 0x6b, 0xc9, 0xda, 0xe6, 0xe3, - 0x1b, 0xee, 0x66, 0x8b, 0x8a, 0x10, 0x42, 0x49, 0x6a, 0x22, 0xdc, 0xb9, 0x34, 0x19, 0x75, 0x0e, - 0x17, 0xae, 0x77, 0xc0, 0x97, 0x7f, 0x37, 0xf1, 0xe5, 0xd0, 0xe8, 0x8c, 0x39, 0xdb, 0xef, 0x8c, - 0xf9, 0xbf, 0xd9, 0xf0, 0x29, 0x66, 0xc3, 0xf9, 0xd4, 0xf9, 0xad, 0x91, 0x89, 0xc5, 0x54, 0x46, - 0xf9, 0x9b, 0x04, 0xf3, 0x5b, 0xa4, 0x8d, 0xe5, 0x49, 0x46, 0xff, 0x26, 0xf6, 0x5b, 0x1c, 0xa1, - 0xaf, 0x92, 0xfa, 0xe8, 0xab, 0xce, 0xbc, 0x2a, 0xbf, 0x0e, 0x93, 0x26, 0x7e, 0x5c, 0x6c, 0xca, - 0x9a, 0xb4, 0x00, 0x9a, 0xf8, 0xf1, 0x4e, 0x6b, 0xe2, 0x4c, 0x08, 0x60, 0xe5, 0x17, 0xc3, 0x70, - 0xbe, 0xc5, 0x50, 0xd7, 0xb6, 0x4c, 0x17, 0xa3, 0x1f, 0x4a, 0x20, 0x3b, 0xe1, 0x02, 0xdd, 0x6e, - 0x92, 0xba, 0x6a, 0x86, 0xc7, 0x6c, 0x4f, 0xac, 0xde, 0xf4, 0x2b, 0x64, 0x3b, 0x06, 0xd9, 0xdd, - 0x26, 0xe2, 0x5d, 0x46, 0xcb, 0x4a, 0xe7, 0x8b, 0x8d, 0x7a, 0xe6, 0x92, 0xd3, 0x1e, 0x43, 0xd0, - 0xf6, 0x7c, 0x07, 0x94, 0xb4, 0x03, 0x17, 0xbb, 0xf1, 0x3f, 0x93, 0x21, 0xd2, 0x84, 0x39, 0x61, - 0x22, 0x62, 0x56, 0xd2, 0x8b, 0xd2, 0x41, 0x3a, 0xff, 0x2b, 0x30, 0x8a, 0x1d, 0xc7, 0x72, 0x44, - 0x99, 0x14, 0x20, 0xa2, 0x52, 0x80, 0xf2, 0x3e, 0x1d, 0x9c, 0xa2, 0xf2, 0xd0, 0x21, 0x20, 0x36, - 0xb4, 0xb1, 0x6f, 0x3e, 0xb5, 0xb1, 0xfd, 0x48, 0x37, 0x4f, 0x6d, 0xa1, 0x8e, 0xb9, 0xc5, 0x46, - 0x3d, 0x93, 0xa6, 0xb3, 0x59, 0x08, 0x14, 0x3d, 0x9d, 0x6a, 0x5e, 0x53, 0x3e, 0x48, 0xc0, 0x28, - 0xad, 0xd4, 0xc1, 0x18, 0x2b, 0x75, 0x1f, 0x63, 0x51, 0x01, 0xa6, 0xfd, 0x40, 0x2c, 0x1e, 0xa8, - 0x65, 0x8f, 0x5b, 0x29, 0xb1, 0x0b, 0x2e, 0x7f, 0x69, 0x83, 0xae, 0x88, 0x17, 0x5c, 0xd1, 0x15, - 0x74, 0x13, 0x12, 0xb4, 0xe1, 0x60, 0xfd, 0x07, 0x1f, 0xdf, 0x68, 0xda, 0x24, 0x60, 0xd6, 0x37, - 0x88, 0x69, 0x33, 0x84, 0x92, 0xe3, 0x40, 0xdb, 0x14, 0x9f, 0x96, 0xcd, 0x3e, 0xf4, 0x38, 0x50, - 0x78, 0x0b, 0x71, 0x42, 0x00, 0xa3, 0x0a, 0x4c, 0x07, 0xb5, 0xd9, 0xd0, 0xab, 0xba, 0xe7, 0xdf, - 0xff, 0x2e, 0x52, 0xc7, 0x52, 0x67, 0x04, 0xc5, 0xf8, 0x3e, 0x45, 0x60, 0xd1, 0x4c, 0x9c, 0x2b, - 0x3b, 0x91, 0x85, 0x48, 0x6f, 0x31, 0x15, 0x5d, 0x43, 0xbf, 0x92, 0xe0, 0x72, 0x93, 0xa4, 0x62, - 0xe9, 0x34, 0x38, 0xc5, 0xc5, 0xb2, 0xa1, 0xba, 0x2e, 0xbb, 0x8a, 0x19, 0x17, 0x6e, 0x83, 0xdb, - 0x29, 0x90, 0x3b, 0xf5, 0x4f, 0x73, 0x9e, 0x10, 0x6d, 0xab, 0x55, 0xcc, 0x74, 0x5a, 0x69, 0xd4, - 0x33, 0x2f, 0x3b, 0xbd, 0x70, 0x05, 0x57, 0x5c, 0xea, 0x89, 0x8c, 0xf6, 0x20, 0x61, 0x63, 0xa7, - 0xaa, 0xbb, 0x2e, 0x6d, 0xc4, 0xd9, 0x4d, 0xf5, 0xbc, 0xa0, 0xdb, 0x4e, 0xb8, 0xca, 0xbc, 0x2e, - 0xa0, 0x8b, 0x5e, 0x17, 0xc0, 0xa4, 0xe9, 0x2b, 0x5b, 0x8e, 0x66, 0x99, 0x98, 0x5d, 0xfd, 0x4f, - 0xf0, 0x69, 0x87, 0xc3, 0x22, 0xd3, 0x0e, 0x87, 0xa1, 0x07, 0x30, 0xc3, 0x7a, 0xf5, 0xa2, 0x86, - 0x6d, 0x07, 0x97, 0x69, 0xe3, 0x12, 0xa7, 0x9b, 0xbd, 0x44, 0x02, 0x9d, 0x2d, 0xae, 0x07, 0x6b, - 0x91, 0xdd, 0x48, 0x35, 0xaf, 0xa2, 0xf5, 0x60, 0x48, 0x81, 0x16, 0x93, 0xfa, 0x1e, 0x53, 0xd2, - 0x7f, 0x97, 0x20, 0x21, 0x38, 0x00, 0xed, 0xc2, 0x84, 0x5b, 0x2b, 0x1d, 0xe1, 0x72, 0x90, 0x30, - 0x17, 0xdb, 0xbb, 0x2a, 0xbb, 0xc7, 0xd0, 0x78, 0x37, 0xc3, 0x69, 0x22, 0xdd, 0x0c, 0x87, 0xd1, - 0x94, 0x85, 0x9d, 0x12, 0xbb, 0x7c, 0xf2, 0x53, 0x16, 0x01, 0x44, 0x52, 0x16, 0x01, 0xa4, 0xdf, - 0x81, 0x71, 0xce, 0x97, 0x1c, 0xe0, 0x63, 0xdd, 0xd4, 0xc4, 0x03, 0x4c, 0xbe, 0xc5, 0x03, 0x4c, - 0xbe, 0x83, 0x83, 0x3e, 0xdc, 0xfd, 0xa0, 0xa7, 0x75, 0x38, 0xd7, 0xe6, 0x18, 0x3c, 0x41, 0xd2, - 0x95, 0x7a, 0xb6, 0x01, 0x3f, 0x96, 0xe0, 0x72, 0x7f, 0x11, 0xdf, 0x9f, 0xf8, 0x7b, 0xa2, 0x78, - 0x7f, 0xc8, 0x8b, 0x30, 0x6c, 0x92, 0xd6, 0x4b, 0xc1, 0xb3, 0x6f, 0xb9, 0x94, 0xef, 0x8f, 0xc2, - 0x85, 0x2e, 0x2a, 0x92, 0xf9, 0x62, 0xa1, 0xaa, 0xbe, 0xa7, 0x57, 0x6b, 0xd5, 0x70, 0xb8, 0x38, - 0x70, 0xd4, 0x32, 0x29, 0x8b, 0x3c, 0xf4, 0xbe, 0xd4, 0xcb, 0xd0, 0xec, 0x03, 0xc6, 0xc1, 0x87, - 0x6e, 0x70, 0x7a, 0xa1, 0x5e, 0x57, 0xdb, 0x63, 0x88, 0xf5, 0xba, 0x03, 0x0a, 0xfa, 0xb5, 0x04, - 0x97, 0x3a, 0xaa, 0x48, 0x73, 0x9f, 0x65, 0x19, 0x34, 0xa8, 0x13, 0xab, 0xf9, 0x27, 0x55, 0x35, - 0x77, 0xba, 0x63, 0x59, 0x06, 0x53, 0xf8, 0xe5, 0x46, 0x3d, 0xf3, 0x52, 0xb5, 0x1b, 0x9e, 0xa0, - 0xf6, 0x73, 0x5d, 0x11, 0x49, 0xb3, 0xd1, 0xcd, 0x39, 0x67, 0x15, 0xf7, 0x4a, 0x6f, 0x33, 0xfb, - 0x13, 0xfd, 0x30, 0x1a, 0xf3, 0x2f, 0xb4, 0xfa, 0x97, 0x30, 0x1c, 0x2c, 0xee, 0x95, 0xdf, 0x0c, - 0x43, 0xa6, 0x07, 0x0f, 0xf4, 0xb3, 0x3e, 0x02, 0x73, 0xad, 0x1f, 0x6d, 0xce, 0x34, 0x38, 0x3f, - 0x8f, 0xfd, 0x55, 0x0a, 0x10, 0xa7, 0x75, 0xe0, 0xbe, 0xee, 0x7a, 0xe8, 0x06, 0x8c, 0xd1, 0x76, - 0xde, 0xaf, 0x13, 0x10, 0xd6, 0x09, 0x56, 0x73, 0xd8, 0xaa, 0x58, 0x73, 0x18, 0x44, 0xd9, 0x07, - 0xc4, 0xee, 0x60, 0x0d, 0xa1, 0x07, 0x46, 0xb7, 0x21, 0x59, 0x66, 0x50, 0xac, 0x09, 0xb3, 0x0a, - 0x7d, 0x97, 0x09, 0x16, 0xa2, 0x13, 0xcb, 0xa4, 0x08, 0x57, 0xfe, 0x23, 0x41, 0x8a, 0xdf, 0xd8, - 0x87, 0x5c, 0xbf, 0x0d, 0xc8, 0x0e, 0x60, 0x4d, 0xa3, 0xc0, 0x35, 0xbe, 0x8b, 0x51, 0x92, 0x16, - 0x00, 0xaf, 0xa3, 0x99, 0x46, 0x3d, 0x73, 0xc1, 0x6e, 0x5e, 0x13, 0xb4, 0x99, 0x69, 0x59, 0x4c, - 0x1b, 0x30, 0xdf, 0x9e, 0xdb, 0x99, 0xa4, 0xdc, 0x9b, 0x30, 0x4d, 0xdd, 0x7f, 0x07, 0x07, 0x4f, - 0x16, 0x7d, 0x76, 0xc1, 0xca, 0xeb, 0x80, 0x28, 0x69, 0x9e, 0x36, 0x2b, 0x83, 0x52, 0x7f, 0x19, - 0x66, 0x29, 0xf5, 0xbe, 0x59, 0x7e, 0x22, 0xfa, 0xdb, 0x20, 0xef, 0x79, 0x0e, 0x56, 0xab, 0xba, - 0x59, 0x69, 0xb6, 0xe0, 0x79, 0x88, 0x99, 0xb5, 0x2a, 0x65, 0x91, 0x64, 0x8e, 0x32, 0x6b, 0x55, - 0xd1, 0x51, 0x66, 0xad, 0x1a, 0xa8, 0xbf, 0x8e, 0x0d, 0xec, 0xe1, 0x41, 0xc5, 0x7f, 0x24, 0x01, - 0xb0, 0x3b, 0xf3, 0x4d, 0xf3, 0xc0, 0xea, 0x7b, 0x72, 0xb8, 0x09, 0x09, 0x1a, 0xd0, 0x5a, 0xf1, - 0xc8, 0xa2, 0xcd, 0x8d, 0xb4, 0x3c, 0xca, 0x5a, 0x7e, 0x06, 0xde, 0xb2, 0x22, 0x1d, 0x0e, 0x84, - 0x50, 0x42, 0x6a, 0x60, 0xd5, 0xf5, 0x49, 0x63, 0x21, 0x29, 0x03, 0x37, 0x93, 0x86, 0x50, 0xe5, - 0x31, 0x9c, 0x63, 0xbe, 0xb6, 0x35, 0xd5, 0x0b, 0x27, 0xdf, 0xd7, 0xc4, 0xb7, 0xa9, 0xe8, 0x61, - 0xec, 0x36, 0x8a, 0x0f, 0x30, 0xd9, 0xd5, 0x40, 0xce, 0xa9, 0x5e, 0xf9, 0xb0, 0x9d, 0xf4, 0x77, - 0x20, 0x79, 0xa0, 0xea, 0x86, 0x7f, 0x0b, 0xeb, 0x1f, 0x30, 0x39, 0xd4, 0x22, 0x4a, 0xc0, 0x4e, - 0x35, 0x23, 0x79, 0xa3, 0x39, 0x4d, 0x4c, 0x8a, 0xf0, 0xc0, 0xde, 0x3c, 0xbd, 0xa7, 0xfb, 0xbc, - 0xec, 0x6d, 0x92, 0xde, 0xdb, 0xde, 0x28, 0xc1, 0x00, 0xf6, 0x26, 0x20, 0x5e, 0x30, 0xb5, 0x07, - 0xaa, 0x73, 0x8c, 0x1d, 0xe5, 0x43, 0x09, 0xe6, 0xa2, 0x27, 0xe3, 0x01, 0x76, 0x5d, 0xb5, 0x82, - 0xd1, 0x17, 0x06, 0xb3, 0xff, 0xee, 0x50, 0xf8, 0x24, 0x12, 0xc3, 0xa6, 0xc6, 0xab, 0xea, 0x14, - 0x25, 0x0b, 0xe4, 0xb1, 0xf3, 0x85, 0xc5, 0x26, 0xfb, 0xee, 0xd0, 0x2e, 0xc1, 0xcf, 0x8d, 0xc3, - 0x28, 0x3e, 0xc1, 0xa6, 0xa7, 0xfc, 0x52, 0xe2, 0x1b, 0xd2, 0xf4, 0x38, 0xda, 0xef, 0xa9, 0xb9, - 0x13, 0xce, 0xdb, 0xb4, 0x6e, 0x62, 0x7f, 0x2c, 0xa0, 0x6f, 0xb4, 0x4d, 0x4b, 0xe2, 0x1b, 0x6d, - 0xd3, 0x12, 0x7b, 0xd2, 0xb6, 0x0c, 0x7f, 0xd6, 0xe6, 0x4f, 0xda, 0x96, 0xd1, 0xf4, 0xa4, 0x6d, - 0x19, 0xae, 0xf2, 0x2f, 0xc9, 0x4f, 0x6f, 0x91, 0xa7, 0xbf, 0xcf, 0x5c, 0xe5, 0x75, 0x88, 0x1f, - 0xf1, 0x87, 0x37, 0xa6, 0x76, 0xcb, 0x73, 0x1c, 0xbd, 0x2f, 0x0d, 0x70, 0xc4, 0xfb, 0xd2, 0x00, - 0x18, 0x1a, 0x3e, 0xd2, 0xcb, 0xf0, 0xab, 0x69, 0x48, 0x08, 0xff, 0x09, 0x41, 0x09, 0x18, 0xe7, - 0x9f, 0xa9, 0xa1, 0xab, 0x57, 0x20, 0x21, 0xfc, 0x77, 0x00, 0x4d, 0xc2, 0xc4, 0xb6, 0xa5, 0xe1, - 0x1d, 0xcb, 0xf1, 0x52, 0x43, 0xe4, 0xeb, 0x2e, 0x56, 0x35, 0x83, 0xa0, 0x4a, 0x57, 0x7f, 0x22, - 0xc1, 0x84, 0xaf, 0x22, 0x02, 0x18, 0x7b, 0x63, 0xbf, 0xb0, 0x5f, 0x58, 0x4f, 0x0d, 0x11, 0x86, - 0x3b, 0x85, 0xed, 0xf5, 0xcd, 0xed, 0x3b, 0x29, 0x89, 0x7c, 0xec, 0xee, 0x6f, 0x6f, 0x93, 0x8f, - 0x61, 0x94, 0x84, 0xf8, 0xde, 0x7e, 0x3e, 0x5f, 0x28, 0xac, 0x17, 0xd6, 0x53, 0x31, 0x42, 0xb4, - 0xb1, 0xb6, 0x79, 0xbf, 0xb0, 0x9e, 0x1a, 0x21, 0x78, 0xfb, 0xdb, 0xf7, 0xb6, 0x1f, 0xbe, 0xb5, - 0x9d, 0x1a, 0x65, 0x78, 0xb9, 0x07, 0x9b, 0x8f, 0x1e, 0x15, 0xd6, 0x53, 0x63, 0x04, 0xef, 0x7e, - 0x61, 0x6d, 0xaf, 0xb0, 0x9e, 0x1a, 0x27, 0x4b, 0x3b, 0xbb, 0x85, 0xc2, 0x83, 0x1d, 0xb2, 0x34, - 0x41, 0x3e, 0xf3, 0x6b, 0xdb, 0xf9, 0xc2, 0x7d, 0xc2, 0x25, 0x4e, 0x34, 0xdc, 0x2d, 0x6c, 0x15, - 0xf2, 0x64, 0x11, 0x56, 0x7f, 0x37, 0x0a, 0x93, 0x74, 0x87, 0xfd, 0xbb, 0xe8, 0x57, 0x21, 0xc1, - 0x8e, 0x20, 0xbb, 0x0d, 0x12, 0xce, 0x47, 0x7a, 0xbe, 0xe5, 0x95, 0xa0, 0x40, 0x7c, 0xa6, 0x0c, - 0xa1, 0xdb, 0x30, 0x29, 0x10, 0xb9, 0x68, 0x2a, 0xa4, 0x22, 0x2d, 0x4f, 0xfa, 0x39, 0xfa, 0xdd, - 0x29, 0x2b, 0x28, 0x43, 0x44, 0x2a, 0x4b, 0x74, 0x03, 0x4a, 0x15, 0x88, 0x7a, 0x4b, 0x8d, 0xa6, - 0x52, 0x65, 0x08, 0x7d, 0x05, 0x12, 0xac, 0xf0, 0x31, 0xa9, 0xe7, 0x43, 0xfa, 0x48, 0x3d, 0xec, - 0xa2, 0x42, 0x16, 0x26, 0xee, 0x60, 0x8f, 0x91, 0xcf, 0x86, 0xe4, 0x61, 0x19, 0x4e, 0x0b, 0xa6, - 0x28, 0x43, 0x68, 0x0b, 0xe2, 0x3e, 0xbe, 0x8b, 0x98, 0x7e, 0x9d, 0x0a, 0x78, 0x3a, 0xdd, 0x66, - 0x99, 0x67, 0x31, 0x65, 0xe8, 0x15, 0x89, 0x68, 0xcf, 0xba, 0x8e, 0x16, 0xed, 0x23, 0xcd, 0x48, - 0x17, 0xed, 0xd7, 0x21, 0xe9, 0x77, 0x1e, 0x8c, 0xc7, 0x82, 0x50, 0x77, 0xa2, 0x2d, 0x49, 0x57, - 0x2e, 0x53, 0x3c, 0xa5, 0x3d, 0xe4, 0x6c, 0x84, 0x74, 0x1e, 0x4d, 0x76, 0x5d, 0xb8, 0xe4, 0x20, - 0xc9, 0x92, 0xcc, 0xc3, 0x36, 0xf6, 0x88, 0xd9, 0xa7, 0x33, 0x8f, 0xd5, 0xef, 0xc5, 0x61, 0x8c, - 0xdd, 0x86, 0xa2, 0x37, 0x01, 0xd8, 0x2f, 0xda, 0x36, 0xcc, 0xb5, 0xfd, 0x87, 0x4b, 0x7a, 0xbe, - 0xfd, 0x15, 0xaa, 0xb2, 0xf0, 0x9d, 0x3f, 0xfc, 0xe5, 0x07, 0xc3, 0xe7, 0x94, 0xa9, 0x95, 0x93, - 0xeb, 0x2b, 0x47, 0x56, 0x89, 0xff, 0x0f, 0xf8, 0x96, 0x74, 0x15, 0xbd, 0x05, 0xc0, 0xb4, 0x89, - 0xf2, 0x8d, 0x6a, 0xc8, 0x54, 0x6f, 0x6d, 0xd5, 0x5b, 0x19, 0xb3, 0x3e, 0x9c, 0x30, 0xfe, 0x3a, - 0x4c, 0x06, 0x8c, 0xf7, 0xb0, 0xc7, 0x7d, 0xd8, 0xe6, 0x8f, 0x17, 0x1d, 0xed, 0xbf, 0x48, 0x99, - 0xcf, 0x2b, 0x33, 0x9c, 0xb9, 0x8b, 0x3d, 0x81, 0xbf, 0x09, 0x29, 0xf1, 0xe2, 0x9e, 0xaa, 0x7f, - 0xa1, 0xfd, 0x95, 0x3e, 0x13, 0x73, 0xb1, 0xdb, 0x7d, 0xbf, 0x92, 0xa1, 0xc2, 0x16, 0x94, 0x59, - 0xdf, 0x12, 0xe1, 0xee, 0x1e, 0x13, 0x79, 0x6f, 0x43, 0x82, 0xef, 0x3d, 0x15, 0x15, 0xb8, 0xba, - 0x29, 0x20, 0xe6, 0xda, 0x8e, 0x12, 0x4a, 0x9a, 0xb2, 0x9f, 0x55, 0xa6, 0x7d, 0xf6, 0x7c, 0x44, - 0x20, 0x9c, 0xef, 0x0c, 0x9e, 0xa1, 0x66, 0x29, 0xbb, 0x29, 0x25, 0x4e, 0xd8, 0xd1, 0x72, 0x4e, - 0x18, 0x95, 0x9f, 0x2e, 0x6b, 0xbd, 0x40, 0x99, 0x2e, 0x2a, 0x0b, 0x84, 0x69, 0x89, 0x60, 0x61, - 0x6d, 0x85, 0xbd, 0x8a, 0xf2, 0xee, 0x86, 0x08, 0xd9, 0x1e, 0x3c, 0xb3, 0x5d, 0xa0, 0x8c, 0xe7, - 0xd2, 0xa9, 0x40, 0xdb, 0x95, 0x6f, 0x91, 0x7a, 0xfa, 0x3e, 0x57, 0xfa, 0x69, 0x92, 0x1e, 0x57, - 0x3a, 0x1d, 0x51, 0xba, 0x46, 0x71, 0x04, 0xa5, 0xdf, 0x7e, 0xca, 0xc4, 0x28, 0x53, 0x29, 0xe8, - 0x6a, 0x8b, 0x05, 0x68, 0x63, 0xa0, 0x84, 0xc9, 0xf9, 0xa0, 0x56, 0x3e, 0xda, 0x33, 0x4a, 0xa4, - 0x3c, 0xd0, 0x10, 0x12, 0xfd, 0xc1, 0x1c, 0xf1, 0x8a, 0x84, 0x6e, 0xc1, 0xd8, 0x5d, 0xfa, 0xef, - 0x79, 0xd4, 0xc1, 0xd2, 0x34, 0x3b, 0xa6, 0x0c, 0x29, 0x7f, 0x88, 0xcb, 0xc7, 0x41, 0xe7, 0xfa, - 0xf6, 0x6f, 0x3f, 0x59, 0x94, 0x3e, 0xfe, 0x64, 0x51, 0xfa, 0xf3, 0x27, 0x8b, 0xd2, 0x87, 0x9f, - 0x2e, 0x0e, 0x7d, 0xfc, 0xe9, 0xe2, 0xd0, 0x1f, 0x3f, 0x5d, 0x1c, 0xfa, 0xea, 0x4b, 0x15, 0xdd, - 0x3b, 0xac, 0x95, 0xb2, 0x65, 0xab, 0xba, 0xa2, 0x3a, 0x55, 0x55, 0x53, 0x6d, 0xc7, 0x3a, 0xc2, - 0x65, 0x8f, 0x7f, 0xad, 0xf0, 0x7f, 0xee, 0x7f, 0x34, 0x3c, 0xbb, 0x46, 0x01, 0x3b, 0x6c, 0x39, - 0xbb, 0x69, 0x65, 0xd7, 0x6c, 0xbd, 0x34, 0x46, 0x75, 0x78, 0xf5, 0xbf, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x6e, 0xeb, 0x95, 0x77, 0xa7, 0x30, 0x00, 0x00, +func (m *BatchQueueUpdateResponse) XXX_Size() int { + return m.Size() +} +func (m *BatchQueueUpdateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BatchQueueUpdateResponse.DiscardUnknown(m) } -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 +var xxx_messageInfo_BatchQueueUpdateResponse proto.InternalMessageInfo -// QueueServiceClient is the client API for QueueService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type QueueServiceClient interface { - CreateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) - CreateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueCreateResponse, error) - UpdateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) - UpdateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueUpdateResponse, error) - DeleteQueue(ctx context.Context, in *QueueDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) - GetQueue(ctx context.Context, in *QueueGetRequest, opts ...grpc.CallOption) (*Queue, error) - GetQueues(ctx context.Context, in *StreamingQueueGetRequest, opts ...grpc.CallOption) (QueueService_GetQueuesClient, error) - CordonQueue(ctx context.Context, in *QueueCordonRequest, opts ...grpc.CallOption) (*types.Empty, error) - UncordonQueue(ctx context.Context, in *QueueUncordonRequest, opts ...grpc.CallOption) (*types.Empty, error) - PreemptOnQueue(ctx context.Context, in *QueuePreemptRequest, opts ...grpc.CallOption) (*types.Empty, error) - CancelOnQueue(ctx context.Context, in *QueueCancelRequest, opts ...grpc.CallOption) (*types.Empty, error) +func (m *BatchQueueUpdateResponse) GetFailedQueues() []*QueueUpdateResponse { + if m != nil { + return m.FailedQueues + } + return nil } -type queueServiceClient struct { - cc *grpc.ClientConn +type QueueCreateResponse struct { + Queue *Queue `protobuf:"bytes,1,opt,name=queue,proto3" json:"queue,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` } -func NewQueueServiceClient(cc *grpc.ClientConn) QueueServiceClient { - return &queueServiceClient{cc} +func (m *QueueCreateResponse) Reset() { *m = QueueCreateResponse{} } +func (m *QueueCreateResponse) String() string { return proto.CompactTextString(m) } +func (*QueueCreateResponse) ProtoMessage() {} +func (*QueueCreateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{34} } - -func (c *queueServiceClient) CreateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) { - out := new(types.Empty) - err := c.cc.Invoke(ctx, "/api.QueueService/CreateQueue", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *QueueCreateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } - -func (c *queueServiceClient) CreateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueCreateResponse, error) { - out := new(BatchQueueCreateResponse) - err := c.cc.Invoke(ctx, "/api.QueueService/CreateQueues", in, out, opts...) - if err != nil { - return nil, err +func (m *QueueCreateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueueCreateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return out, nil } - -func (c *queueServiceClient) UpdateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) { - out := new(types.Empty) - err := c.cc.Invoke(ctx, "/api.QueueService/UpdateQueue", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *QueueCreateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueueCreateResponse.Merge(m, src) +} +func (m *QueueCreateResponse) XXX_Size() int { + return m.Size() +} +func (m *QueueCreateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueueCreateResponse.DiscardUnknown(m) } -func (c *queueServiceClient) UpdateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueUpdateResponse, error) { - out := new(BatchQueueUpdateResponse) - err := c.cc.Invoke(ctx, "/api.QueueService/UpdateQueues", in, out, opts...) - if err != nil { - return nil, err +var xxx_messageInfo_QueueCreateResponse proto.InternalMessageInfo + +func (m *QueueCreateResponse) GetQueue() *Queue { + if m != nil { + return m.Queue } - return out, nil + return nil } -func (c *queueServiceClient) DeleteQueue(ctx context.Context, in *QueueDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) { - out := new(types.Empty) - err := c.cc.Invoke(ctx, "/api.QueueService/DeleteQueue", in, out, opts...) - if err != nil { - return nil, err +func (m *QueueCreateResponse) GetError() string { + if m != nil { + return m.Error } - return out, nil + return "" } -func (c *queueServiceClient) GetQueue(ctx context.Context, in *QueueGetRequest, opts ...grpc.CallOption) (*Queue, error) { - out := new(Queue) - err := c.cc.Invoke(ctx, "/api.QueueService/GetQueue", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +type BatchQueueCreateResponse struct { + FailedQueues []*QueueCreateResponse `protobuf:"bytes,1,rep,name=failed_queues,json=failedQueues,proto3" json:"failedQueues,omitempty"` +} + +func (m *BatchQueueCreateResponse) Reset() { *m = BatchQueueCreateResponse{} } +func (m *BatchQueueCreateResponse) String() string { return proto.CompactTextString(m) } +func (*BatchQueueCreateResponse) ProtoMessage() {} +func (*BatchQueueCreateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{35} +} +func (m *BatchQueueCreateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BatchQueueCreateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BatchQueueCreateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BatchQueueCreateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BatchQueueCreateResponse.Merge(m, src) +} +func (m *BatchQueueCreateResponse) XXX_Size() int { + return m.Size() +} +func (m *BatchQueueCreateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BatchQueueCreateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BatchQueueCreateResponse proto.InternalMessageInfo + +func (m *BatchQueueCreateResponse) GetFailedQueues() []*QueueCreateResponse { + if m != nil { + return m.FailedQueues + } + return nil +} + +// Indicates the end of streams +type EndMarker struct { +} + +func (m *EndMarker) Reset() { *m = EndMarker{} } +func (m *EndMarker) String() string { return proto.CompactTextString(m) } +func (*EndMarker) ProtoMessage() {} +func (*EndMarker) Descriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{36} +} +func (m *EndMarker) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EndMarker) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EndMarker.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EndMarker) XXX_Merge(src proto.Message) { + xxx_messageInfo_EndMarker.Merge(m, src) +} +func (m *EndMarker) XXX_Size() int { + return m.Size() +} +func (m *EndMarker) XXX_DiscardUnknown() { + xxx_messageInfo_EndMarker.DiscardUnknown(m) +} + +var xxx_messageInfo_EndMarker proto.InternalMessageInfo + +type StreamingQueueMessage struct { + // Types that are valid to be assigned to Event: + // *StreamingQueueMessage_Queue + // *StreamingQueueMessage_End + Event isStreamingQueueMessage_Event `protobuf_oneof:"event"` +} + +func (m *StreamingQueueMessage) Reset() { *m = StreamingQueueMessage{} } +func (m *StreamingQueueMessage) String() string { return proto.CompactTextString(m) } +func (*StreamingQueueMessage) ProtoMessage() {} +func (*StreamingQueueMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{37} +} +func (m *StreamingQueueMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StreamingQueueMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StreamingQueueMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StreamingQueueMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamingQueueMessage.Merge(m, src) +} +func (m *StreamingQueueMessage) XXX_Size() int { + return m.Size() +} +func (m *StreamingQueueMessage) XXX_DiscardUnknown() { + xxx_messageInfo_StreamingQueueMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_StreamingQueueMessage proto.InternalMessageInfo + +type isStreamingQueueMessage_Event interface { + isStreamingQueueMessage_Event() + MarshalTo([]byte) (int, error) + Size() int +} + +type StreamingQueueMessage_Queue struct { + Queue *Queue `protobuf:"bytes,1,opt,name=queue,proto3,oneof" json:"queue,omitempty"` +} +type StreamingQueueMessage_End struct { + End *EndMarker `protobuf:"bytes,2,opt,name=end,proto3,oneof" json:"end,omitempty"` +} + +func (*StreamingQueueMessage_Queue) isStreamingQueueMessage_Event() {} +func (*StreamingQueueMessage_End) isStreamingQueueMessage_Event() {} + +func (m *StreamingQueueMessage) GetEvent() isStreamingQueueMessage_Event { + if m != nil { + return m.Event + } + return nil +} + +func (m *StreamingQueueMessage) GetQueue() *Queue { + if x, ok := m.GetEvent().(*StreamingQueueMessage_Queue); ok { + return x.Queue + } + return nil +} + +func (m *StreamingQueueMessage) GetEnd() *EndMarker { + if x, ok := m.GetEvent().(*StreamingQueueMessage_End); ok { + return x.End + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*StreamingQueueMessage) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*StreamingQueueMessage_Queue)(nil), + (*StreamingQueueMessage_End)(nil), + } +} + +type QueuePreemptRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + PriorityClasses []string `protobuf:"bytes,2,rep,name=priorityClasses,proto3" json:"priorityClasses,omitempty"` + // If empty, jobs on all pools will be preempted + Pools []string `protobuf:"bytes,3,rep,name=pools,proto3" json:"pools,omitempty"` +} + +func (m *QueuePreemptRequest) Reset() { *m = QueuePreemptRequest{} } +func (m *QueuePreemptRequest) String() string { return proto.CompactTextString(m) } +func (*QueuePreemptRequest) ProtoMessage() {} +func (*QueuePreemptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{38} +} +func (m *QueuePreemptRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueuePreemptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueuePreemptRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueuePreemptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueuePreemptRequest.Merge(m, src) +} +func (m *QueuePreemptRequest) XXX_Size() int { + return m.Size() +} +func (m *QueuePreemptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueuePreemptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueuePreemptRequest proto.InternalMessageInfo + +func (m *QueuePreemptRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *QueuePreemptRequest) GetPriorityClasses() []string { + if m != nil { + return m.PriorityClasses + } + return nil +} + +func (m *QueuePreemptRequest) GetPools() []string { + if m != nil { + return m.Pools + } + return nil +} + +type QueueCancelRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + PriorityClasses []string `protobuf:"bytes,2,rep,name=priorityClasses,proto3" json:"priorityClasses,omitempty"` + // In practice jobs are only cancellable from non-terminal states + JobStates []JobState `protobuf:"varint,3,rep,packed,name=jobStates,proto3,enum=api.JobState" json:"jobStates,omitempty"` + // If empty, jobs on all pools will be cancelled + Pools []string `protobuf:"bytes,4,rep,name=pools,proto3" json:"pools,omitempty"` +} + +func (m *QueueCancelRequest) Reset() { *m = QueueCancelRequest{} } +func (m *QueueCancelRequest) String() string { return proto.CompactTextString(m) } +func (*QueueCancelRequest) ProtoMessage() {} +func (*QueueCancelRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_e998bacb27df16c1, []int{39} +} +func (m *QueueCancelRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueueCancelRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueueCancelRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueueCancelRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueueCancelRequest.Merge(m, src) +} +func (m *QueueCancelRequest) XXX_Size() int { + return m.Size() +} +func (m *QueueCancelRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueueCancelRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueueCancelRequest proto.InternalMessageInfo + +func (m *QueueCancelRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *QueueCancelRequest) GetPriorityClasses() []string { + if m != nil { + return m.PriorityClasses + } + return nil +} + +func (m *QueueCancelRequest) GetJobStates() []JobState { + if m != nil { + return m.JobStates + } + return nil +} + +func (m *QueueCancelRequest) GetPools() []string { + if m != nil { + return m.Pools + } + return nil +} + +func init() { + proto.RegisterEnum("api.IngressType", IngressType_name, IngressType_value) + proto.RegisterEnum("api.ServiceType", ServiceType_name, ServiceType_value) + proto.RegisterEnum("api.JobState", JobState_name, JobState_value) + proto.RegisterEnum("api.RetryAction", RetryAction_name, RetryAction_value) + proto.RegisterEnum("api.ExitCodeOperator", ExitCodeOperator_name, ExitCodeOperator_value) + proto.RegisterType((*JobSubmitRequestItem)(nil), "api.JobSubmitRequestItem") + proto.RegisterMapType((map[string]string)(nil), "api.JobSubmitRequestItem.AnnotationsEntry") + proto.RegisterMapType((map[string]string)(nil), "api.JobSubmitRequestItem.LabelsEntry") + proto.RegisterMapType((map[string]string)(nil), "api.JobSubmitRequestItem.RequiredNodeLabelsEntry") + proto.RegisterType((*IngressConfig)(nil), "api.IngressConfig") + proto.RegisterMapType((map[string]string)(nil), "api.IngressConfig.AnnotationsEntry") + proto.RegisterType((*ServiceConfig)(nil), "api.ServiceConfig") + proto.RegisterType((*JobSubmitRequest)(nil), "api.JobSubmitRequest") + proto.RegisterType((*JobPreemptRequest)(nil), "api.JobPreemptRequest") + proto.RegisterType((*JobCancelRequest)(nil), "api.JobCancelRequest") + proto.RegisterType((*JobSetCancelRequest)(nil), "api.JobSetCancelRequest") + proto.RegisterType((*JobSetFilter)(nil), "api.JobSetFilter") + proto.RegisterType((*Job)(nil), "api.Job") + proto.RegisterMapType((map[string]string)(nil), "api.Job.AnnotationsEntry") + proto.RegisterMapType((map[string]string)(nil), "api.Job.LabelsEntry") + proto.RegisterMapType((map[string]string)(nil), "api.Job.RequiredNodeLabelsEntry") + proto.RegisterType((*JobReprioritizeRequest)(nil), "api.JobReprioritizeRequest") + proto.RegisterType((*JobReprioritizeResponse)(nil), "api.JobReprioritizeResponse") + proto.RegisterMapType((map[string]string)(nil), "api.JobReprioritizeResponse.ReprioritizationResultsEntry") + proto.RegisterType((*JobSubmitResponseItem)(nil), "api.JobSubmitResponseItem") + proto.RegisterType((*JobSubmitResponse)(nil), "api.JobSubmitResponse") + proto.RegisterType((*Queue)(nil), "api.Queue") + proto.RegisterMapType((map[string]string)(nil), "api.Queue.LabelsEntry") + proto.RegisterMapType((map[string]*PriorityClassResourceLimits)(nil), "api.Queue.ResourceLimitsByPriorityClassNameEntry") + proto.RegisterMapType((map[string]float64)(nil), "api.Queue.ResourceLimitsEntry") + proto.RegisterType((*Queue_Permissions)(nil), "api.Queue.Permissions") + proto.RegisterType((*Queue_Permissions_Subject)(nil), "api.Queue.Permissions.Subject") + proto.RegisterType((*PriorityClassResourceLimits)(nil), "api.PriorityClassResourceLimits") + proto.RegisterMapType((map[string]*PriorityClassPoolResourceLimits)(nil), "api.PriorityClassResourceLimits.MaximumResourceFractionByPoolEntry") + proto.RegisterMapType((map[string]float64)(nil), "api.PriorityClassResourceLimits.MaximumResourceFractionEntry") + proto.RegisterType((*PriorityClassPoolResourceLimits)(nil), "api.PriorityClassPoolResourceLimits") + proto.RegisterMapType((map[string]float64)(nil), "api.PriorityClassPoolResourceLimits.MaximumResourceFractionEntry") + proto.RegisterType((*QueueList)(nil), "api.QueueList") + proto.RegisterType((*CancellationResult)(nil), "api.CancellationResult") + proto.RegisterType((*PreemptionResult)(nil), "api.PreemptionResult") + proto.RegisterMapType((map[string]string)(nil), "api.PreemptionResult.PreemptionResultsEntry") + proto.RegisterType((*RetryPolicy)(nil), "api.RetryPolicy") + proto.RegisterType((*RetryRule)(nil), "api.RetryRule") + proto.RegisterType((*RetryExitCodeMatcher)(nil), "api.RetryExitCodeMatcher") + proto.RegisterType((*RetryPolicyGetRequest)(nil), "api.RetryPolicyGetRequest") + proto.RegisterType((*RetryPolicyDeleteRequest)(nil), "api.RetryPolicyDeleteRequest") + proto.RegisterType((*RetryPolicyListRequest)(nil), "api.RetryPolicyListRequest") + proto.RegisterType((*RetryPolicyList)(nil), "api.RetryPolicyList") + proto.RegisterType((*QueueGetRequest)(nil), "api.QueueGetRequest") + proto.RegisterType((*QueueCordonRequest)(nil), "api.QueueCordonRequest") + proto.RegisterType((*QueueUncordonRequest)(nil), "api.QueueUncordonRequest") + proto.RegisterType((*StreamingQueueGetRequest)(nil), "api.StreamingQueueGetRequest") + proto.RegisterType((*QueueDeleteRequest)(nil), "api.QueueDeleteRequest") + proto.RegisterType((*JobSetInfo)(nil), "api.JobSetInfo") + proto.RegisterType((*QueueUpdateResponse)(nil), "api.QueueUpdateResponse") + proto.RegisterType((*BatchQueueUpdateResponse)(nil), "api.BatchQueueUpdateResponse") + proto.RegisterType((*QueueCreateResponse)(nil), "api.QueueCreateResponse") + proto.RegisterType((*BatchQueueCreateResponse)(nil), "api.BatchQueueCreateResponse") + proto.RegisterType((*EndMarker)(nil), "api.EndMarker") + proto.RegisterType((*StreamingQueueMessage)(nil), "api.StreamingQueueMessage") + proto.RegisterType((*QueuePreemptRequest)(nil), "api.QueuePreemptRequest") + proto.RegisterType((*QueueCancelRequest)(nil), "api.QueueCancelRequest") +} + +func init() { proto.RegisterFile("pkg/api/submit.proto", fileDescriptor_e998bacb27df16c1) } + +var fileDescriptor_e998bacb27df16c1 = []byte{ + // 3862 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3b, 0x4d, 0x6c, 0x23, 0x59, + 0x5a, 0x29, 0xe7, 0xd7, 0x9f, 0xe3, 0xc4, 0x79, 0x9d, 0xa4, 0x1d, 0xa7, 0x3b, 0xce, 0xd4, 0xec, + 0xf4, 0xa6, 0xb3, 0xbd, 0xce, 0x4c, 0x86, 0x15, 0xdd, 0xc3, 0xec, 0x34, 0xb1, 0xe3, 0xee, 0x49, + 0xa6, 0xdb, 0xc9, 0x38, 0xc9, 0x6e, 0xcf, 0x08, 0x51, 0x94, 0x5d, 0x2f, 0xe9, 0x4a, 0xec, 0x2a, + 0x4f, 0x55, 0xb9, 0xbb, 0x03, 0xec, 0x01, 0x84, 0xc4, 0x91, 0x15, 0x1c, 0x41, 0xc0, 0x81, 0x03, + 0x5a, 0x4e, 0x1c, 0xb8, 0x20, 0xae, 0x48, 0x88, 0xd3, 0x22, 0x84, 0x04, 0x17, 0x0b, 0xcd, 0xb0, + 0x20, 0x59, 0xe2, 0xc0, 0x85, 0x03, 0x42, 0x08, 0xbd, 0xef, 0xbd, 0xaa, 0x7a, 0xe5, 0xbf, 0xc4, + 0xe9, 0xce, 0xcc, 0x65, 0x6f, 0xf1, 0xf7, 0xff, 0xbe, 0xf7, 0xbd, 0xef, 0xe7, 0xbd, 0x0a, 0xcc, + 0x37, 0xce, 0x4e, 0x36, 0xf4, 0x86, 0xb9, 0xe1, 0x36, 0x2b, 0x75, 0xd3, 0xcb, 0x35, 0x1c, 0xdb, + 0xb3, 0xc9, 0xa8, 0xde, 0x30, 0x33, 0xcb, 0x27, 0xb6, 0x7d, 0x52, 0xa3, 0x1b, 0x08, 0xaa, 0x34, + 0x8f, 0x37, 0x68, 0xbd, 0xe1, 0x9d, 0x73, 0x8a, 0x4c, 0xb6, 0x13, 0xe9, 0x99, 0x75, 0xea, 0x7a, + 0x7a, 0xbd, 0x21, 0x08, 0xd4, 0xb3, 0xfb, 0x6e, 0xce, 0xb4, 0x51, 0x76, 0xd5, 0x76, 0xe8, 0xc6, + 0x8b, 0xf7, 0x36, 0x4e, 0xa8, 0x45, 0x1d, 0xdd, 0xa3, 0x86, 0xa0, 0x59, 0x93, 0x68, 0x2c, 0xea, + 0xbd, 0xb4, 0x9d, 0x33, 0xd3, 0x3a, 0xe9, 0x45, 0x79, 0x4b, 0xa8, 0x63, 0x94, 0xba, 0x65, 0xd9, + 0x9e, 0xee, 0x99, 0xb6, 0xe5, 0x0a, 0x6c, 0xb0, 0x88, 0xe7, 0x54, 0xaf, 0x79, 0xcf, 0x39, 0x54, + 0xfd, 0xcf, 0x38, 0xcc, 0xef, 0xda, 0x95, 0x03, 0x5c, 0x58, 0x99, 0x7e, 0xd1, 0xa4, 0xae, 0xb7, + 0xe3, 0xd1, 0x3a, 0xd9, 0x84, 0xa9, 0x86, 0x63, 0xda, 0x8e, 0xe9, 0x9d, 0xa7, 0x95, 0x55, 0x65, + 0x4d, 0xc9, 0x2f, 0xb6, 0x5b, 0x59, 0xe2, 0xc3, 0xee, 0xd9, 0x75, 0xd3, 0xc3, 0xb5, 0x96, 0x03, + 0x3a, 0xf2, 0x3d, 0x88, 0x5b, 0x7a, 0x9d, 0xba, 0x0d, 0xbd, 0x4a, 0xd3, 0xa3, 0xab, 0xca, 0x5a, + 0x3c, 0x7f, 0xb3, 0xdd, 0xca, 0xde, 0x08, 0x80, 0x12, 0x57, 0x48, 0x49, 0xde, 0x87, 0x78, 0xb5, + 0x66, 0x52, 0xcb, 0xd3, 0x4c, 0x23, 0x3d, 0x85, 0x6c, 0xa8, 0x8b, 0x03, 0x77, 0x0c, 0x59, 0x97, + 0x0f, 0x23, 0x07, 0x30, 0x51, 0xd3, 0x2b, 0xb4, 0xe6, 0xa6, 0xc7, 0x56, 0x47, 0xd7, 0x12, 0x9b, + 0xef, 0xe4, 0xf4, 0x86, 0x99, 0xeb, 0xb5, 0x94, 0xdc, 0x13, 0xa4, 0x2b, 0x5a, 0x9e, 0x73, 0x9e, + 0x9f, 0x6f, 0xb7, 0xb2, 0x29, 0xce, 0x28, 0x89, 0x15, 0xa2, 0xc8, 0x09, 0x24, 0x24, 0xc7, 0xa5, + 0xc7, 0x51, 0xf2, 0x7a, 0x7f, 0xc9, 0x5b, 0x21, 0x31, 0x17, 0xbf, 0xd4, 0x6e, 0x65, 0x17, 0x24, + 0x11, 0x92, 0x0e, 0x59, 0x32, 0xf9, 0x5d, 0x05, 0xe6, 0x1d, 0xfa, 0x45, 0xd3, 0x74, 0xa8, 0xa1, + 0x59, 0xb6, 0x41, 0x35, 0xb1, 0x98, 0x09, 0x54, 0xf9, 0x5e, 0x7f, 0x95, 0x65, 0xc1, 0x55, 0xb2, + 0x0d, 0x2a, 0x2f, 0x4c, 0x6d, 0xb7, 0xb2, 0xb7, 0x9c, 0x2e, 0x64, 0x68, 0x40, 0x5a, 0x29, 0x93, + 0x6e, 0x3c, 0xd9, 0x83, 0xa9, 0x86, 0x6d, 0x68, 0x6e, 0x83, 0x56, 0xd3, 0xb1, 0x55, 0x65, 0x2d, + 0xb1, 0xb9, 0x9c, 0xe3, 0x11, 0x87, 0x36, 0xb0, 0xa8, 0xcc, 0xbd, 0x78, 0x2f, 0xb7, 0x6f, 0x1b, + 0x07, 0x0d, 0x5a, 0xc5, 0xfd, 0x9c, 0x6b, 0xf0, 0x1f, 0x11, 0xd9, 0x93, 0x02, 0x48, 0xf6, 0x21, + 0xee, 0x0b, 0x74, 0xd3, 0x93, 0xb8, 0x9c, 0x81, 0x12, 0x79, 0x58, 0xf1, 0x1f, 0x6e, 0x24, 0xac, + 0x04, 0x8c, 0x14, 0x60, 0xd2, 0xb4, 0x4e, 0x1c, 0xea, 0xba, 0xe9, 0x38, 0xca, 0x23, 0x28, 0x68, + 0x87, 0xc3, 0x0a, 0xb6, 0x75, 0x6c, 0x9e, 0xe4, 0x17, 0x98, 0x61, 0x82, 0x4c, 0x92, 0xe2, 0x73, + 0x92, 0x47, 0x30, 0xe5, 0x52, 0xe7, 0x85, 0x59, 0xa5, 0x6e, 0x1a, 0x24, 0x29, 0x07, 0x1c, 0x28, + 0xa4, 0xa0, 0x31, 0x3e, 0x9d, 0x6c, 0x8c, 0x0f, 0x63, 0x31, 0xee, 0x56, 0x9f, 0x53, 0xa3, 0x59, + 0xa3, 0x4e, 0x3a, 0x11, 0xc6, 0x78, 0x00, 0x94, 0x63, 0x3c, 0x00, 0x92, 0x47, 0x90, 0xa2, 0xaf, + 0x3c, 0xea, 0x58, 0x7a, 0x4d, 0x3b, 0xb5, 0x2b, 0x5a, 0xd3, 0x31, 0xd3, 0x49, 0xe4, 0xbe, 0xd5, + 0x6e, 0x65, 0xd3, 0x3e, 0x6e, 0xd7, 0xae, 0x1c, 0x39, 0xa6, 0x24, 0x62, 0x26, 0x8a, 0xc9, 0xe8, + 0x90, 0x90, 0x76, 0x9d, 0xbc, 0x0d, 0xa3, 0x67, 0x94, 0x1f, 0xd0, 0x78, 0x7e, 0xae, 0xdd, 0xca, + 0x26, 0xcf, 0xa8, 0x7c, 0x36, 0x19, 0x96, 0xdc, 0x85, 0xf1, 0x17, 0x7a, 0xad, 0x49, 0x71, 0x7f, + 0xe3, 0xf9, 0x1b, 0xed, 0x56, 0x76, 0x16, 0x01, 0x12, 0x21, 0xa7, 0xf8, 0x20, 0x76, 0x5f, 0xc9, + 0x1c, 0x43, 0xaa, 0x33, 0xae, 0xaf, 0x45, 0x4f, 0x1d, 0x6e, 0xf6, 0x09, 0xe6, 0xeb, 0x50, 0xb7, + 0x3b, 0x36, 0x35, 0x9d, 0x4a, 0xaa, 0xff, 0x35, 0x0a, 0xc9, 0x48, 0xe0, 0x90, 0x0f, 0x60, 0xcc, + 0x3b, 0x6f, 0x50, 0x54, 0x36, 0xb3, 0x99, 0x92, 0x43, 0xeb, 0xf0, 0xbc, 0x41, 0x31, 0x63, 0xcc, + 0x30, 0x8a, 0x48, 0xb8, 0x23, 0x0f, 0x33, 0xa1, 0x61, 0x3b, 0x9e, 0x9b, 0x8e, 0xad, 0x8e, 0xae, + 0x25, 0xb9, 0x09, 0x08, 0x90, 0x4d, 0x40, 0x00, 0xf9, 0xb5, 0x68, 0x6a, 0x19, 0xc5, 0x10, 0x7c, + 0xbb, 0x3b, 0x90, 0xaf, 0x9e, 0x53, 0x1e, 0x40, 0xc2, 0xab, 0xb9, 0x1a, 0xb5, 0xf4, 0x4a, 0x8d, + 0x1a, 0xe9, 0xb1, 0x55, 0x65, 0x6d, 0x2a, 0x9f, 0x6e, 0xb7, 0xb2, 0xf3, 0x1e, 0xf3, 0x2b, 0x42, + 0x25, 0x5e, 0x08, 0xa1, 0x98, 0x81, 0xa9, 0xe3, 0x69, 0x2c, 0x27, 0xa7, 0xc7, 0xa5, 0x0c, 0x4c, + 0x1d, 0xaf, 0xa4, 0xd7, 0x69, 0x24, 0x03, 0x0b, 0x18, 0x79, 0x08, 0xc9, 0xa6, 0x4b, 0xb5, 0x6a, + 0xad, 0xe9, 0x7a, 0xd4, 0xd9, 0xd9, 0x4f, 0x4f, 0xa0, 0xc6, 0x4c, 0xbb, 0x95, 0x5d, 0x6c, 0xba, + 0xb4, 0xe0, 0xc3, 0x25, 0xe6, 0x69, 0x19, 0xfe, 0x75, 0x05, 0x9a, 0xfa, 0x47, 0x0a, 0x24, 0x23, + 0xc7, 0x9c, 0xdc, 0xef, 0xb1, 0xe7, 0x82, 0x02, 0xf7, 0x9c, 0x74, 0xef, 0xf9, 0xf0, 0x3b, 0x7e, + 0x07, 0xc6, 0xd0, 0x9f, 0xbc, 0x10, 0xa2, 0x48, 0x2b, 0xea, 0x4b, 0xc4, 0xab, 0xff, 0xa2, 0x40, + 0xaa, 0x33, 0xd5, 0x33, 0x3d, 0x5f, 0x34, 0x69, 0x93, 0x0a, 0x4f, 0xa0, 0x1e, 0x04, 0xc8, 0x7a, + 0x10, 0x40, 0x7e, 0x01, 0x80, 0x65, 0x14, 0x97, 0x62, 0xfd, 0x8c, 0x85, 0xbb, 0x77, 0x6a, 0x57, + 0x0e, 0x68, 0x47, 0xfd, 0xf4, 0x61, 0xc4, 0x80, 0x39, 0xc6, 0xe5, 0x70, 0x7d, 0x1a, 0x23, 0xf0, + 0xa3, 0x72, 0xa9, 0x6f, 0xf5, 0xc9, 0xdf, 0x6e, 0xb7, 0xb2, 0x4b, 0xa7, 0x76, 0x45, 0x82, 0xc9, + 0x2b, 0x9f, 0xed, 0x40, 0xa9, 0xff, 0xa0, 0xc0, 0xdc, 0xae, 0x5d, 0xd9, 0x77, 0x28, 0x23, 0xf8, + 0xda, 0x16, 0xf7, 0x5d, 0x98, 0x64, 0x5c, 0xa6, 0xc1, 0x97, 0x14, 0xe7, 0x65, 0xff, 0xd4, 0xae, + 0xec, 0x18, 0x91, 0xb2, 0xcf, 0x21, 0xe4, 0x1e, 0x4c, 0x38, 0x54, 0x77, 0x6d, 0x0b, 0x0f, 0x8d, + 0xa0, 0xe6, 0x10, 0x99, 0x9a, 0x43, 0xd4, 0xff, 0xe5, 0xfb, 0x55, 0xd0, 0xad, 0x2a, 0xad, 0xf9, + 0x4b, 0x5a, 0x87, 0x09, 0xae, 0x51, 0x5e, 0x13, 0x8a, 0x97, 0xd7, 0x84, 0x80, 0x2b, 0xae, 0x29, + 0x70, 0xda, 0xe8, 0x85, 0x4e, 0x93, 0x96, 0x3f, 0x36, 0xd4, 0xf2, 0xc7, 0x2f, 0xb1, 0xfc, 0x9f, + 0x29, 0x70, 0x63, 0x17, 0x8d, 0x8a, 0x7a, 0x20, 0xba, 0x2a, 0x65, 0xd8, 0x55, 0xc5, 0x2e, 0x5c, + 0xd5, 0x43, 0x98, 0x38, 0x36, 0x6b, 0x1e, 0x75, 0xd0, 0x03, 0x89, 0xcd, 0xb9, 0x20, 0x4c, 0xa9, + 0xf7, 0x08, 0x11, 0xdc, 0x72, 0x4e, 0x24, 0x5b, 0xce, 0x21, 0x43, 0x6e, 0xf3, 0x27, 0x30, 0x2d, + 0xcb, 0x26, 0xbf, 0x04, 0x13, 0xae, 0xa7, 0x7b, 0xd4, 0x4d, 0x2b, 0xab, 0xa3, 0x6b, 0x33, 0x9b, + 0xc9, 0x40, 0x3d, 0x83, 0x72, 0x61, 0x9c, 0x40, 0x16, 0xc6, 0x21, 0xea, 0x9f, 0xcf, 0xc2, 0xe8, + 0xae, 0x5d, 0x21, 0xab, 0x10, 0x0b, 0x9c, 0x93, 0x6a, 0xb7, 0xb2, 0xd3, 0xa6, 0xec, 0x96, 0x98, + 0x69, 0x44, 0x9b, 0xe1, 0xe4, 0x25, 0x9b, 0xe1, 0x6b, 0x8f, 0xa8, 0x48, 0x67, 0x3f, 0x79, 0xe9, + 0xce, 0x3e, 0x1f, 0x34, 0xe9, 0xbc, 0x71, 0x9b, 0xf7, 0x7d, 0x36, 0x44, 0x4f, 0xfe, 0x83, 0x68, + 0xe1, 0x84, 0x68, 0x8a, 0xba, 0x7a, 0xb9, 0x7c, 0xd1, 0xa7, 0x03, 0x4f, 0xa0, 0x82, 0xd5, 0x40, + 0xc1, 0x9b, 0x6e, 0xb8, 0xef, 0xc2, 0xb8, 0xfd, 0xd2, 0xa2, 0x8e, 0x98, 0x74, 0xd0, 0xeb, 0x08, + 0x90, 0xbd, 0x8e, 0x00, 0x42, 0x61, 0x19, 0xdd, 0xaf, 0xe1, 0x4f, 0xf7, 0xb9, 0xd9, 0xd0, 0x9a, + 0x2e, 0x75, 0xb4, 0x13, 0xc7, 0x6e, 0x36, 0xdc, 0xf4, 0x2c, 0x9e, 0xed, 0x3b, 0xed, 0x56, 0x56, + 0x45, 0xb2, 0x3d, 0x9f, 0xea, 0xc8, 0xa5, 0xce, 0x63, 0xa4, 0x91, 0x64, 0xa6, 0xfb, 0xd1, 0x90, + 0xdf, 0x51, 0xe0, 0x4e, 0xd5, 0xae, 0x37, 0x58, 0x13, 0x42, 0x0d, 0x6d, 0x90, 0xca, 0x1b, 0xab, + 0xca, 0xda, 0x74, 0xfe, 0xdd, 0x76, 0x2b, 0x7b, 0x2f, 0xe4, 0xf8, 0xf4, 0x62, 0xe5, 0xea, 0xc5, + 0xd4, 0x91, 0x89, 0x73, 0xec, 0x92, 0x13, 0xa7, 0x3c, 0xbd, 0x8c, 0xbf, 0xf1, 0xe9, 0x65, 0xfa, + 0x4d, 0x4c, 0x2f, 0x7f, 0xaa, 0xc0, 0xaa, 0x98, 0x03, 0x4c, 0xeb, 0x44, 0x73, 0xa8, 0x6b, 0x37, + 0x9d, 0x2a, 0xd5, 0x44, 0x68, 0xd4, 0xa9, 0xe5, 0xb9, 0xe9, 0x05, 0xb4, 0x7d, 0xad, 0x97, 0xa6, + 0xb2, 0x60, 0x28, 0x4b, 0xf4, 0xf9, 0x7b, 0xed, 0x56, 0x76, 0x2d, 0x94, 0xda, 0x8b, 0x46, 0x32, + 0x66, 0x65, 0x30, 0x25, 0xf9, 0x04, 0x26, 0xab, 0x0e, 0xd5, 0x3d, 0x6a, 0x60, 0x0f, 0x97, 0xd8, + 0xcc, 0xe4, 0xf8, 0x55, 0x42, 0xce, 0xbf, 0xb9, 0xc8, 0x1d, 0xfa, 0x37, 0x17, 0x7c, 0xd0, 0x12, + 0xe4, 0xf2, 0xa0, 0x25, 0x40, 0xf2, 0xb4, 0x36, 0xf3, 0x46, 0xa6, 0xb5, 0xd4, 0x6b, 0x4c, 0x6b, + 0xbf, 0x02, 0x89, 0xb3, 0xfb, 0xae, 0xe6, 0x1b, 0x34, 0x87, 0xa2, 0xde, 0x92, 0xdd, 0x1c, 0x5e, + 0xa9, 0x30, 0x67, 0x0b, 0x2b, 0x79, 0xdb, 0x7c, 0x76, 0xdf, 0xdd, 0xe9, 0x32, 0x11, 0x42, 0x28, + 0x4b, 0x4d, 0x4c, 0xba, 0xd0, 0x96, 0x26, 0xfd, 0xc3, 0x45, 0xd8, 0x1d, 0xc8, 0x15, 0xbf, 0x3b, + 0xe4, 0x0a, 0x68, 0x74, 0xc6, 0x9c, 0xbf, 0xec, 0x8c, 0xf9, 0xf3, 0xd9, 0xf0, 0x35, 0x66, 0xc3, + 0xc5, 0xd4, 0xcd, 0xdd, 0xb1, 0xa9, 0x95, 0x54, 0x56, 0xfd, 0x77, 0x05, 0x16, 0x77, 0x59, 0x1b, + 0x2b, 0x92, 0x8c, 0xf9, 0xeb, 0xd4, 0x6f, 0x71, 0xa4, 0xbe, 0x4a, 0xb9, 0x44, 0x5f, 0x75, 0xed, + 0x55, 0xf9, 0x43, 0x98, 0xb6, 0xe8, 0x4b, 0xad, 0x23, 0x6b, 0x62, 0x01, 0xb4, 0xe8, 0xcb, 0xfd, + 0xee, 0xc4, 0x99, 0x90, 0xc0, 0xea, 0x5f, 0xc4, 0xe0, 0x66, 0xd7, 0x42, 0xdd, 0x86, 0x6d, 0xb9, + 0x94, 0xfc, 0xa1, 0x02, 0x69, 0x27, 0x44, 0xe0, 0x76, 0xb3, 0xd4, 0xd5, 0xac, 0x79, 0x7c, 0xed, + 0x89, 0xcd, 0x07, 0x7e, 0x85, 0xec, 0x25, 0x20, 0x57, 0xee, 0x60, 0x2e, 0x73, 0x5e, 0x5e, 0x3a, + 0xdf, 0x69, 0xb7, 0xb2, 0x6f, 0x39, 0xbd, 0x29, 0x24, 0x6b, 0x6f, 0xf6, 0x21, 0xc9, 0x38, 0x70, + 0x6b, 0x90, 0xfc, 0x6b, 0x19, 0x22, 0x2d, 0x58, 0x90, 0x26, 0x22, 0xbe, 0x4a, 0xbc, 0x28, 0x1d, + 0xa6, 0xf3, 0xbf, 0x0b, 0xe3, 0xd4, 0x71, 0x6c, 0x47, 0xd6, 0x89, 0x00, 0x99, 0x14, 0x01, 0xea, + 0x8f, 0x70, 0x70, 0x8a, 0xea, 0x23, 0xcf, 0x81, 0xf0, 0xa1, 0x8d, 0xff, 0x16, 0x53, 0x1b, 0xdf, + 0x8f, 0x4c, 0xe7, 0xd4, 0x16, 0xda, 0x98, 0x5f, 0x69, 0xb7, 0xb2, 0x19, 0x9c, 0xcd, 0x42, 0xa0, + 0xec, 0xe9, 0x54, 0x27, 0x4e, 0xfd, 0xdb, 0x04, 0x8c, 0x63, 0xa5, 0x0e, 0xc6, 0x58, 0x65, 0xf0, + 0x18, 0x4b, 0x8a, 0x30, 0xeb, 0x07, 0xa2, 0x76, 0xac, 0x57, 0x3d, 0xb1, 0x4a, 0x85, 0x5f, 0x70, + 0xf9, 0xa8, 0x47, 0x88, 0x91, 0x2f, 0xb8, 0xa2, 0x18, 0xf2, 0x00, 0x12, 0xd8, 0x70, 0xf0, 0xfe, + 0x43, 0x8c, 0x6f, 0x98, 0x36, 0x19, 0x98, 0xf7, 0x0d, 0x72, 0xda, 0x0c, 0xa1, 0xec, 0x38, 0x60, + 0x9b, 0xe2, 0xf3, 0xf2, 0xd9, 0x07, 0x8f, 0x03, 0xc2, 0xbb, 0x98, 0x13, 0x12, 0x98, 0x9c, 0xc0, + 0x6c, 0x50, 0x9b, 0x6b, 0x66, 0xdd, 0xf4, 0xfc, 0xfb, 0xdf, 0x15, 0x74, 0x2c, 0x3a, 0x23, 0x28, + 0xc6, 0x4f, 0x90, 0x80, 0x47, 0x33, 0x73, 0x6e, 0xda, 0x89, 0x20, 0x22, 0xbd, 0xc5, 0x4c, 0x14, + 0x47, 0xfe, 0x4a, 0x81, 0x3b, 0x1d, 0x9a, 0xb4, 0xca, 0x79, 0x70, 0x8a, 0xb5, 0x6a, 0x4d, 0x77, + 0x5d, 0x7e, 0x15, 0x33, 0x29, 0xdd, 0x06, 0xf7, 0x32, 0x20, 0x7f, 0xee, 0x9f, 0xe6, 0x02, 0x63, + 0x2a, 0xe9, 0x75, 0xca, 0x6d, 0xda, 0x68, 0xb7, 0xb2, 0xdf, 0x71, 0x2e, 0xa2, 0x95, 0x5c, 0xf1, + 0xd6, 0x85, 0xc4, 0xe4, 0x00, 0x12, 0x0d, 0xea, 0xd4, 0x4d, 0xd7, 0xc5, 0x46, 0x9c, 0xdf, 0x54, + 0x2f, 0x4a, 0xb6, 0xed, 0x87, 0x58, 0xee, 0x75, 0x89, 0x5c, 0xf6, 0xba, 0x04, 0x66, 0x4d, 0x5f, + 0xd5, 0x76, 0x0c, 0xdb, 0xa2, 0xfc, 0xea, 0x7f, 0x4a, 0x4c, 0x3b, 0x02, 0x16, 0x99, 0x76, 0x04, + 0x8c, 0x3c, 0x85, 0x39, 0xde, 0xab, 0x6b, 0x06, 0x6d, 0x38, 0xb4, 0x8a, 0x8d, 0x4b, 0x1c, 0x37, + 0x7b, 0x95, 0x05, 0x3a, 0x47, 0x6e, 0x07, 0xb8, 0xc8, 0x6e, 0xa4, 0x3a, 0xb1, 0x64, 0x3b, 0x18, + 0x52, 0xa0, 0x6b, 0x49, 0x97, 0x1f, 0x53, 0x3e, 0x84, 0x69, 0x87, 0x7a, 0xce, 0xb9, 0xd6, 0xb0, + 0x6b, 0x66, 0xf5, 0x5c, 0x5c, 0x0d, 0xa3, 0x1b, 0x10, 0xbe, 0x8f, 0x60, 0xd9, 0x0d, 0x12, 0x38, + 0xf3, 0x1f, 0x0a, 0x24, 0x24, 0xf7, 0x91, 0x32, 0x4c, 0xb9, 0xcd, 0xca, 0x29, 0xad, 0x06, 0xe9, + 0x76, 0xa5, 0xb7, 0xa3, 0x73, 0x07, 0x9c, 0x4c, 0xf4, 0x42, 0x82, 0x27, 0xd2, 0x0b, 0x09, 0x18, + 0x26, 0x3c, 0xea, 0x54, 0xf8, 0xd5, 0x95, 0x9f, 0xf0, 0x18, 0x20, 0x92, 0xf0, 0x18, 0x20, 0xf3, + 0x19, 0x4c, 0x0a, 0xb9, 0xec, 0xf8, 0x9f, 0x99, 0x96, 0x21, 0x1f, 0x7f, 0xf6, 0x5b, 0x3e, 0xfe, + 0xec, 0x77, 0x90, 0x26, 0x62, 0x83, 0xd3, 0x44, 0xc6, 0x84, 0x1b, 0x3d, 0x0e, 0xd1, 0x15, 0x52, + 0xb6, 0x72, 0x61, 0x13, 0xf1, 0xc7, 0x0a, 0xdc, 0xb9, 0xdc, 0x79, 0xb9, 0x9c, 0xfa, 0x4f, 0x64, + 0xf5, 0xfe, 0x88, 0x18, 0x11, 0xd8, 0xa1, 0xed, 0x22, 0x03, 0xaf, 0xbf, 0x61, 0x53, 0x7f, 0x7f, + 0x1c, 0x96, 0x07, 0x98, 0xc8, 0xa6, 0x93, 0xa5, 0xba, 0xfe, 0xca, 0xac, 0x37, 0xeb, 0xe1, 0x68, + 0x72, 0xec, 0xe8, 0x55, 0x56, 0x54, 0x45, 0xe8, 0x7d, 0xff, 0xa2, 0x85, 0xe6, 0x9e, 0x72, 0x09, + 0x3e, 0xf4, 0x91, 0xe0, 0x97, 0xaa, 0x7d, 0xbd, 0x37, 0x85, 0x5c, 0xed, 0xfb, 0x90, 0x90, 0xbf, + 0x56, 0xe0, 0xad, 0xbe, 0x26, 0x62, 0xe6, 0xb4, 0xed, 0x1a, 0x06, 0x75, 0x62, 0xb3, 0x70, 0x55, + 0x53, 0xf3, 0xe7, 0xfb, 0xb6, 0x5d, 0xe3, 0x06, 0x7f, 0xa7, 0xdd, 0xca, 0x7e, 0xbb, 0x3e, 0x88, + 0x4e, 0x32, 0xfb, 0xf6, 0x40, 0x42, 0xd6, 0xaa, 0x0c, 0x72, 0xce, 0x75, 0xc5, 0xbd, 0x7a, 0xf1, + 0x32, 0x2f, 0xa7, 0x7a, 0x2f, 0x1a, 0xf3, 0xdf, 0xea, 0xf6, 0x2f, 0x13, 0x38, 0x5c, 0xdc, 0xab, + 0x7f, 0x13, 0x83, 0xec, 0x05, 0x32, 0xc8, 0x9f, 0x5d, 0x22, 0x30, 0xb7, 0x2e, 0x63, 0xcd, 0xb5, + 0x06, 0xe7, 0x37, 0xb1, 0xbf, 0x6a, 0x11, 0xe2, 0x58, 0x07, 0x9e, 0x98, 0xae, 0x47, 0xee, 0xc3, + 0x04, 0x0e, 0x03, 0x7e, 0x9d, 0x80, 0xb0, 0x4e, 0xf0, 0x8a, 0xc5, 0xb1, 0x72, 0xc5, 0xe2, 0x10, + 0xf5, 0x08, 0x08, 0xbf, 0xc1, 0xad, 0x49, 0x1d, 0x34, 0x79, 0x08, 0xc9, 0x2a, 0x87, 0x52, 0x43, + 0x9a, 0x74, 0xf0, 0x55, 0x27, 0x40, 0x44, 0xe7, 0x9d, 0x69, 0x19, 0xae, 0xfe, 0x9f, 0x02, 0x29, + 0x71, 0xdf, 0x1f, 0x4a, 0xfd, 0x4d, 0x20, 0x8d, 0x00, 0xd6, 0x31, 0x48, 0xdc, 0x13, 0xbb, 0x18, + 0x65, 0xe9, 0x02, 0x88, 0x2a, 0x9c, 0x6d, 0xb7, 0xb2, 0xcb, 0x8d, 0x4e, 0x9c, 0x64, 0xcd, 0x5c, + 0x17, 0x32, 0x53, 0x83, 0xc5, 0xde, 0xd2, 0xae, 0x25, 0xe5, 0xfe, 0x56, 0x0c, 0x12, 0xe5, 0xb0, + 0xb6, 0x5f, 0xba, 0x81, 0x7e, 0x00, 0xbc, 0x25, 0xe0, 0x3d, 0x21, 0x2a, 0x4b, 0xf2, 0xce, 0x17, + 0xc1, 0x18, 0xcd, 0x72, 0xe7, 0x1b, 0x42, 0xc9, 0x21, 0xcc, 0x18, 0xf4, 0x58, 0x6f, 0xd6, 0x3c, + 0x4d, 0x1c, 0x90, 0x51, 0xe9, 0x65, 0x0b, 0x8d, 0xd9, 0xe2, 0xe7, 0x7f, 0xb9, 0xdd, 0xca, 0xde, + 0x14, 0xb4, 0x5b, 0x9d, 0x51, 0x9e, 0x8c, 0x20, 0xc8, 0x03, 0x18, 0x77, 0x9a, 0x35, 0xea, 0x7f, + 0x61, 0x31, 0x13, 0x0a, 0x2b, 0x37, 0x6b, 0x94, 0xfb, 0x01, 0x09, 0x64, 0x3f, 0x20, 0x40, 0xfd, + 0xa7, 0x51, 0x88, 0x07, 0x94, 0xe4, 0x23, 0x98, 0x08, 0xce, 0x6d, 0x6f, 0xb3, 0x30, 0x52, 0xbb, + 0x4e, 0x9d, 0xe0, 0x62, 0x31, 0x69, 0x5b, 0x5a, 0xd5, 0xb6, 0x0c, 0x93, 0x5f, 0x02, 0xc7, 0xc2, + 0x98, 0xb4, 0xad, 0x42, 0x00, 0x97, 0x63, 0x52, 0x86, 0x93, 0x67, 0x28, 0x80, 0xbe, 0x32, 0x3d, + 0xad, 0x6a, 0x1b, 0xd4, 0x15, 0x2f, 0x08, 0x4b, 0xa1, 0x1d, 0xc5, 0x57, 0xa6, 0x57, 0xb0, 0x0d, + 0xfa, 0x54, 0xf7, 0xaa, 0xcf, 0xa9, 0xc3, 0x1b, 0x37, 0xdb, 0xf2, 0xc1, 0x91, 0xfe, 0x55, 0x02, + 0x13, 0x0b, 0x56, 0x6c, 0x4b, 0xf3, 0x58, 0x43, 0x66, 0xf1, 0x29, 0xb9, 0x4e, 0x5d, 0x57, 0x3f, + 0xa1, 0x5a, 0x43, 0xf7, 0x3c, 0xea, 0xf8, 0x6f, 0x0d, 0x77, 0xdb, 0xad, 0xec, 0x3b, 0xb6, 0x75, + 0x18, 0x12, 0x3e, 0xe5, 0x74, 0xfb, 0x9c, 0x4c, 0x92, 0xbf, 0x3c, 0x80, 0x8c, 0x05, 0x09, 0x73, + 0x85, 0xee, 0xd1, 0x13, 0xdb, 0x39, 0x17, 0x0f, 0x36, 0x18, 0x24, 0xb6, 0x55, 0x10, 0x50, 0x39, + 0x48, 0x42, 0x28, 0xc9, 0xc3, 0x8c, 0x6d, 0x69, 0x6e, 0xb3, 0x12, 0x70, 0x4f, 0x20, 0x37, 0x86, + 0x84, 0x6d, 0x1d, 0x84, 0x08, 0x39, 0x24, 0x22, 0x08, 0xf5, 0xf7, 0x14, 0x98, 0xef, 0xe5, 0x2f, + 0xb2, 0x03, 0x53, 0x76, 0x83, 0x3a, 0x3a, 0x1b, 0xfb, 0xf8, 0x26, 0x2f, 0xa0, 0x73, 0x7d, 0xba, + 0x3d, 0x81, 0xe4, 0x7d, 0xaa, 0x4f, 0x2a, 0xf7, 0xa9, 0x3e, 0x8c, 0xdc, 0x83, 0x09, 0x3c, 0x4c, + 0x7c, 0x9b, 0xc7, 0x79, 0x6c, 0x70, 0x88, 0x1c, 0x1b, 0x1c, 0xa2, 0x3e, 0x84, 0x05, 0xe9, 0xb0, + 0x3d, 0xa6, 0xc1, 0x23, 0xe3, 0x25, 0x8f, 0x9d, 0x9a, 0x87, 0xb4, 0x24, 0x60, 0x9b, 0xd6, 0xa8, + 0x47, 0x87, 0x95, 0x91, 0x86, 0x45, 0x49, 0x06, 0xcb, 0xcb, 0x42, 0x82, 0x7a, 0x02, 0xb3, 0x1d, + 0x18, 0x76, 0x58, 0xa5, 0x49, 0xc1, 0x0c, 0x32, 0xb7, 0x74, 0x2a, 0x38, 0x35, 0xdf, 0x99, 0x70, + 0x4c, 0x30, 0x23, 0x0e, 0x48, 0x46, 0x10, 0xea, 0x03, 0x98, 0xc5, 0xa4, 0x7f, 0x05, 0x0f, 0x7c, + 0x08, 0x04, 0x59, 0x0b, 0x38, 0x60, 0x0d, 0xcb, 0xfd, 0x11, 0xcc, 0x23, 0xf7, 0x91, 0x55, 0xbd, + 0x12, 0xff, 0x43, 0x48, 0x1f, 0x78, 0x0e, 0xd5, 0xeb, 0xa6, 0x75, 0xd2, 0xb9, 0x82, 0xb7, 0x61, + 0xd4, 0x6a, 0xd6, 0x51, 0x44, 0x92, 0xa7, 0x67, 0xab, 0x59, 0x97, 0xd3, 0xb3, 0xd5, 0xac, 0x07, + 0xe6, 0x5f, 0x6d, 0xeb, 0x7e, 0xa2, 0x00, 0xf0, 0x77, 0xbe, 0x1d, 0xeb, 0xd8, 0x1e, 0x26, 0x59, + 0x63, 0x19, 0x35, 0xb4, 0x53, 0x1b, 0x47, 0x2a, 0x65, 0x6d, 0x9c, 0x9f, 0x43, 0x0e, 0xde, 0xb5, + 0x23, 0x73, 0x15, 0x84, 0x50, 0xc6, 0x5a, 0xa3, 0xba, 0xeb, 0xb3, 0x8e, 0x86, 0xac, 0x1c, 0xdc, + 0xc9, 0x1a, 0x42, 0xd5, 0x97, 0x70, 0x83, 0xfb, 0xba, 0x61, 0xe8, 0x5e, 0x78, 0x5b, 0xf7, 0x3d, + 0xf9, 0x3d, 0x3d, 0xda, 0x02, 0x0c, 0xba, 0x3e, 0x1c, 0xe2, 0x36, 0xaa, 0x09, 0xe9, 0x3c, 0x3b, + 0xe9, 0xbd, 0xb4, 0x7f, 0x06, 0xc9, 0x63, 0xdd, 0xac, 0xf9, 0x2f, 0x47, 0x7e, 0x38, 0xa7, 0x43, + 0x2b, 0xa2, 0x0c, 0x3c, 0x6f, 0x73, 0x96, 0x4f, 0x3b, 0x9b, 0x93, 0x69, 0x19, 0x1e, 0xac, 0xb7, + 0x80, 0x6f, 0x0b, 0xdf, 0xd4, 0x7a, 0x3b, 0xb4, 0x5f, 0xbc, 0xde, 0x28, 0xc3, 0x10, 0xeb, 0x4d, + 0x40, 0xbc, 0x68, 0x19, 0x4f, 0x75, 0xe7, 0x8c, 0x3a, 0xea, 0x8f, 0x15, 0x58, 0x88, 0x9e, 0x0c, + 0x51, 0x0b, 0xc8, 0x2f, 0x0e, 0xb7, 0xfe, 0x8f, 0x47, 0xc2, 0x67, 0xdc, 0x51, 0x6a, 0x19, 0xa2, + 0x97, 0xe7, 0xf5, 0x3c, 0xd0, 0xc7, 0xcf, 0x17, 0x95, 0x47, 0xfb, 0x8f, 0x47, 0xca, 0x8c, 0x3e, + 0x3f, 0x09, 0xe3, 0xf4, 0x05, 0xb5, 0x3c, 0xf5, 0x2f, 0x15, 0xb1, 0x21, 0x1d, 0x1f, 0x74, 0x5c, + 0xf6, 0xd4, 0x3c, 0x0e, 0xef, 0x08, 0xb1, 0x5b, 0xa7, 0x7e, 0x29, 0xc7, 0xef, 0x4a, 0x3a, 0x50, + 0xf2, 0x77, 0x25, 0x1d, 0x28, 0xfe, 0x19, 0x8e, 0x5d, 0xf3, 0xef, 0x07, 0xc5, 0x67, 0x38, 0x76, + 0xad, 0xe3, 0x33, 0x1c, 0xbb, 0xe6, 0xaa, 0xff, 0xad, 0xf8, 0xe9, 0x2d, 0xf2, 0xb9, 0xc2, 0xd7, + 0x6e, 0xf2, 0x36, 0xc4, 0x4f, 0xc5, 0xc7, 0x02, 0xdc, 0xec, 0xae, 0x4f, 0x08, 0xf0, 0x8d, 0x27, + 0xa0, 0x91, 0xdf, 0x78, 0x02, 0x60, 0xb8, 0xf0, 0xb1, 0x8b, 0x16, 0xbe, 0x9e, 0x81, 0x84, 0xf4, + 0x1d, 0x1b, 0x49, 0xc0, 0xa4, 0xf8, 0x99, 0x1a, 0x59, 0xbf, 0x0b, 0x09, 0xe9, 0x7b, 0x27, 0x32, + 0x0d, 0x53, 0x25, 0xdb, 0xa0, 0xfb, 0xb6, 0xe3, 0xa5, 0x46, 0xd8, 0xaf, 0x8f, 0xa9, 0x6e, 0xd4, + 0x18, 0xa9, 0xb2, 0xfe, 0x27, 0x0a, 0x4c, 0xf9, 0x26, 0x12, 0x80, 0x89, 0x4f, 0x8f, 0x8a, 0x47, + 0xc5, 0xed, 0xd4, 0x08, 0x13, 0xb8, 0x5f, 0x2c, 0x6d, 0xef, 0x94, 0x1e, 0xa7, 0x14, 0xf6, 0xa3, + 0x7c, 0x54, 0x2a, 0xb1, 0x1f, 0x31, 0x92, 0x84, 0xf8, 0xc1, 0x51, 0xa1, 0x50, 0x2c, 0x6e, 0x17, + 0xb7, 0x53, 0xa3, 0x8c, 0xe9, 0xd1, 0xd6, 0xce, 0x93, 0xe2, 0x76, 0x6a, 0x8c, 0xd1, 0x1d, 0x95, + 0x3e, 0x29, 0xed, 0xfd, 0xb0, 0x94, 0x1a, 0xe7, 0x74, 0xf9, 0xa7, 0x3b, 0x87, 0x87, 0xc5, 0xed, + 0xd4, 0x04, 0xa3, 0x7b, 0x52, 0xdc, 0x3a, 0x28, 0x6e, 0xa7, 0x26, 0x19, 0x6a, 0xbf, 0x5c, 0x2c, + 0x3e, 0xdd, 0x67, 0xa8, 0x29, 0xf6, 0xb3, 0xb0, 0x55, 0x2a, 0x14, 0x9f, 0x30, 0x29, 0x71, 0x66, + 0x61, 0xb9, 0xb8, 0x5b, 0x2c, 0x30, 0x24, 0xac, 0x7f, 0x2e, 0xfa, 0x6d, 0xd1, 0xb6, 0xde, 0x82, + 0x74, 0xb9, 0x78, 0x58, 0xfe, 0x4c, 0xdb, 0x2a, 0x1c, 0xee, 0xec, 0x95, 0xb4, 0xa3, 0xd2, 0xc1, + 0x7e, 0xb1, 0xb0, 0xf3, 0x68, 0x07, 0xad, 0x5e, 0x80, 0xb9, 0x08, 0x96, 0x59, 0x96, 0x52, 0xc8, + 0x22, 0x90, 0x08, 0x18, 0x7f, 0xa4, 0x62, 0xeb, 0x0d, 0x48, 0x75, 0xb6, 0x30, 0x44, 0x85, 0x95, + 0xe2, 0xb3, 0x9d, 0x43, 0xad, 0xb0, 0xb7, 0x5d, 0xd4, 0xf6, 0xf6, 0x8b, 0xe5, 0xad, 0xc3, 0xbd, + 0x72, 0x87, 0x9a, 0x25, 0x58, 0xe8, 0x41, 0xb3, 0x53, 0x4a, 0x29, 0xe4, 0x36, 0x2c, 0xf5, 0x40, + 0x95, 0xf6, 0x0e, 0x19, 0x3a, 0xb6, 0xf9, 0xf7, 0xe3, 0x30, 0x8d, 0xf1, 0xea, 0xbf, 0x06, 0xbe, + 0x0f, 0x09, 0x9e, 0x50, 0xf8, 0x7d, 0xbc, 0x74, 0xda, 0x33, 0x8b, 0x5d, 0xef, 0xb4, 0x45, 0x16, + 0x01, 0xea, 0x08, 0x79, 0x08, 0xd3, 0x12, 0x93, 0x4b, 0x66, 0x42, 0x2e, 0xd6, 0x84, 0x64, 0x6e, + 0xe3, 0xef, 0x7e, 0x39, 0x4e, 0x1d, 0x61, 0x5a, 0x79, 0xda, 0x1e, 0x52, 0xab, 0xc4, 0x74, 0xb1, + 0xd6, 0x68, 0x61, 0x50, 0x47, 0xc8, 0x2f, 0x43, 0x82, 0x97, 0x71, 0xae, 0xf5, 0x66, 0xc8, 0x1f, + 0xa9, 0xee, 0x03, 0x4c, 0xc8, 0xc1, 0xd4, 0x63, 0xea, 0x71, 0xf6, 0xf9, 0x90, 0x3d, 0x6c, 0x2a, + 0x32, 0xd2, 0x52, 0xd4, 0x11, 0xb2, 0x0b, 0x71, 0x9f, 0xde, 0x25, 0xdc, 0xbe, 0x7e, 0xed, 0x48, + 0x26, 0xd3, 0x03, 0x2d, 0x72, 0xb2, 0x3a, 0xf2, 0xae, 0xc2, 0xac, 0xe7, 0x3d, 0x54, 0x97, 0xf5, + 0x91, 0xd6, 0x6a, 0x80, 0xf5, 0xdb, 0x90, 0xf4, 0xfb, 0x28, 0x2e, 0x63, 0x49, 0xaa, 0xa2, 0xd1, + 0x06, 0x6b, 0xa0, 0x94, 0x19, 0x91, 0xa0, 0xf7, 0x84, 0x18, 0xa9, 0x38, 0x45, 0x53, 0xf7, 0x00, + 0x29, 0x79, 0x48, 0xf2, 0x94, 0xb9, 0xd7, 0x63, 0x3d, 0x72, 0x2e, 0xed, 0x2f, 0x63, 0xf3, 0x67, + 0x31, 0x20, 0x52, 0x47, 0xeb, 0x87, 0xf4, 0xf7, 0x61, 0xce, 0x0f, 0xb8, 0x70, 0x4e, 0xee, 0xea, + 0x7f, 0xfb, 0xc9, 0x65, 0xec, 0x7e, 0xe4, 0x5c, 0x85, 0x7d, 0x17, 0xe6, 0xfc, 0x68, 0x0a, 0xd9, + 0x6f, 0x77, 0xb2, 0x5f, 0x2a, 0xe0, 0xc8, 0x47, 0x30, 0x83, 0x01, 0x12, 0x0a, 0xca, 0x74, 0x0a, + 0x92, 0x02, 0xa8, 0xcb, 0x46, 0x52, 0x84, 0x54, 0x84, 0xdf, 0xa4, 0x2e, 0x59, 0xee, 0xa4, 0x92, + 0x06, 0x8a, 0xcc, 0x7c, 0x2f, 0xe4, 0xe6, 0xff, 0x4c, 0xc3, 0x04, 0x7f, 0xf7, 0x23, 0x3f, 0x00, + 0xe0, 0x7f, 0x61, 0xb3, 0xb9, 0xd0, 0xf3, 0x5b, 0xce, 0xcc, 0x62, 0xef, 0xc7, 0x42, 0x75, 0xe9, + 0xb7, 0xff, 0xf1, 0xdf, 0xfe, 0x20, 0x76, 0x43, 0x9d, 0xd9, 0x78, 0xf1, 0xde, 0xc6, 0xa9, 0x5d, + 0x11, 0xff, 0xf1, 0xf2, 0x81, 0xb2, 0x4e, 0x7e, 0x08, 0xc0, 0x77, 0x3d, 0x2a, 0x37, 0x1a, 0x09, + 0x3c, 0x44, 0xba, 0xaf, 0x95, 0xba, 0x05, 0xf3, 0x3b, 0x23, 0x26, 0xf8, 0x57, 0x61, 0x3a, 0x10, + 0x7c, 0x40, 0x3d, 0x11, 0xab, 0x3d, 0x3e, 0x31, 0xec, 0x1b, 0x67, 0xb7, 0x50, 0xf8, 0xa2, 0x3a, + 0x27, 0x84, 0xbb, 0xd4, 0x93, 0xe4, 0x5b, 0x90, 0x92, 0x9f, 0xa8, 0xd1, 0xfc, 0xe5, 0xde, 0x8f, + 0xd7, 0x5c, 0xcd, 0xad, 0x41, 0x2f, 0xdb, 0x6a, 0x16, 0x95, 0x2d, 0xa9, 0xf3, 0xfe, 0x4a, 0xa4, + 0x57, 0x6a, 0xca, 0xf4, 0x3d, 0x83, 0x84, 0x38, 0x63, 0xa8, 0x2a, 0x70, 0x75, 0xc7, 0xc1, 0x5b, + 0xe8, 0x79, 0xed, 0xa5, 0x66, 0x50, 0xfc, 0xbc, 0x3a, 0xeb, 0x8b, 0x17, 0xd7, 0x59, 0x4c, 0xf2, + 0xe3, 0xe1, 0x2b, 0xc1, 0x3c, 0x8a, 0x9b, 0x51, 0xe3, 0x4c, 0x1c, 0x36, 0x81, 0x4c, 0x50, 0xf5, + 0xf5, 0xaa, 0xc3, 0xb7, 0x50, 0xe8, 0x8a, 0xba, 0xc4, 0x84, 0x56, 0xf0, 0x06, 0xc0, 0xd8, 0xe0, + 0xdf, 0xff, 0x88, 0x9e, 0x98, 0x29, 0x29, 0x0d, 0x5f, 0x41, 0x96, 0x51, 0xf0, 0x42, 0x26, 0x15, + 0x58, 0xbb, 0xf1, 0x1b, 0xac, 0x0b, 0xfb, 0x91, 0x30, 0xfa, 0x75, 0x8a, 0x8b, 0x30, 0x3a, 0x13, + 0x31, 0xba, 0x89, 0x34, 0x92, 0xd1, 0xcf, 0x5e, 0xb3, 0x00, 0xa5, 0x51, 0x0b, 0x59, 0xef, 0x5a, + 0x01, 0x79, 0x34, 0x54, 0x61, 0x12, 0x72, 0x48, 0xb7, 0x1c, 0xe3, 0x0d, 0x15, 0x2c, 0x11, 0x68, + 0x84, 0xc8, 0xfe, 0xe0, 0x8e, 0x78, 0x57, 0x21, 0x9f, 0xbf, 0x56, 0x86, 0xf6, 0x37, 0x52, 0x45, + 0xf3, 0xf1, 0xa2, 0xe2, 0xbb, 0xfc, 0x5d, 0x94, 0xf9, 0x58, 0x7f, 0xad, 0xf4, 0xad, 0xaa, 0x28, + 0xfb, 0x56, 0xe6, 0x66, 0xa7, 0x6c, 0x29, 0x56, 0xce, 0xde, 0x5c, 0x8a, 0xf7, 0x0f, 0xfc, 0x7a, + 0x3f, 0x7d, 0x44, 0x7b, 0xbd, 0x1a, 0xe0, 0x2b, 0x20, 0x7d, 0x15, 0xe8, 0x6f, 0xa4, 0x48, 0x44, + 0x77, 0x5c, 0xd2, 0xc3, 0xc4, 0x7d, 0x00, 0x13, 0x1f, 0xe3, 0xff, 0x05, 0x92, 0x3e, 0x6e, 0xc8, + 0xf0, 0xb4, 0xcc, 0x89, 0x0a, 0xcf, 0x69, 0xf5, 0x2c, 0x98, 0x6f, 0x9f, 0xfd, 0xdd, 0x97, 0x2b, + 0xca, 0x4f, 0xbf, 0x5c, 0x51, 0xfe, 0xf5, 0xcb, 0x15, 0xe5, 0xc7, 0x5f, 0xad, 0x8c, 0xfc, 0xf4, + 0xab, 0x95, 0x91, 0x7f, 0xfe, 0x6a, 0x65, 0xe4, 0xf3, 0x6f, 0x9f, 0x98, 0xde, 0xf3, 0x66, 0x25, + 0x57, 0xb5, 0xeb, 0x1b, 0xba, 0x53, 0xd7, 0x0d, 0xbd, 0xe1, 0xd8, 0xa7, 0xb4, 0xea, 0x89, 0x5f, + 0x1b, 0xe2, 0x7f, 0x12, 0x7f, 0x12, 0x9b, 0xdf, 0x42, 0xc0, 0x3e, 0x47, 0xe7, 0x76, 0xec, 0xdc, + 0x56, 0xc3, 0xac, 0x4c, 0xa0, 0x0d, 0xef, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x91, + 0x76, 0xef, 0x81, 0x39, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueueServiceClient is the client API for QueueService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueueServiceClient interface { + CreateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) + CreateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueCreateResponse, error) + UpdateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) + UpdateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueUpdateResponse, error) + DeleteQueue(ctx context.Context, in *QueueDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) + GetQueue(ctx context.Context, in *QueueGetRequest, opts ...grpc.CallOption) (*Queue, error) + GetQueues(ctx context.Context, in *StreamingQueueGetRequest, opts ...grpc.CallOption) (QueueService_GetQueuesClient, error) + CordonQueue(ctx context.Context, in *QueueCordonRequest, opts ...grpc.CallOption) (*types.Empty, error) + UncordonQueue(ctx context.Context, in *QueueUncordonRequest, opts ...grpc.CallOption) (*types.Empty, error) + PreemptOnQueue(ctx context.Context, in *QueuePreemptRequest, opts ...grpc.CallOption) (*types.Empty, error) + CancelOnQueue(ctx context.Context, in *QueueCancelRequest, opts ...grpc.CallOption) (*types.Empty, error) +} + +type queueServiceClient struct { + cc *grpc.ClientConn +} + +func NewQueueServiceClient(cc *grpc.ClientConn) QueueServiceClient { + return &queueServiceClient{cc} +} + +func (c *queueServiceClient) CreateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.QueueService/CreateQueue", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queueServiceClient) CreateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueCreateResponse, error) { + out := new(BatchQueueCreateResponse) + err := c.cc.Invoke(ctx, "/api.QueueService/CreateQueues", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queueServiceClient) UpdateQueue(ctx context.Context, in *Queue, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.QueueService/UpdateQueue", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queueServiceClient) UpdateQueues(ctx context.Context, in *QueueList, opts ...grpc.CallOption) (*BatchQueueUpdateResponse, error) { + out := new(BatchQueueUpdateResponse) + err := c.cc.Invoke(ctx, "/api.QueueService/UpdateQueues", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queueServiceClient) DeleteQueue(ctx context.Context, in *QueueDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.QueueService/DeleteQueue", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queueServiceClient) GetQueue(ctx context.Context, in *QueueGetRequest, opts ...grpc.CallOption) (*Queue, error) { + out := new(Queue) + err := c.cc.Invoke(ctx, "/api.QueueService/GetQueue", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } func (c *queueServiceClient) GetQueues(ctx context.Context, in *StreamingQueueGetRequest, opts ...grpc.CallOption) (QueueService_GetQueuesClient, error) { @@ -3098,6 +3589,222 @@ var _QueueService_serviceDesc = grpc.ServiceDesc{ Metadata: "pkg/api/submit.proto", } +// RetryPolicyServiceClient is the client API for RetryPolicyService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type RetryPolicyServiceClient interface { + CreateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) + UpdateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) + DeleteRetryPolicy(ctx context.Context, in *RetryPolicyDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) + GetRetryPolicy(ctx context.Context, in *RetryPolicyGetRequest, opts ...grpc.CallOption) (*RetryPolicy, error) + GetRetryPolicies(ctx context.Context, in *RetryPolicyListRequest, opts ...grpc.CallOption) (*RetryPolicyList, error) +} + +type retryPolicyServiceClient struct { + cc *grpc.ClientConn +} + +func NewRetryPolicyServiceClient(cc *grpc.ClientConn) RetryPolicyServiceClient { + return &retryPolicyServiceClient{cc} +} + +func (c *retryPolicyServiceClient) CreateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.RetryPolicyService/CreateRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *retryPolicyServiceClient) UpdateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.RetryPolicyService/UpdateRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *retryPolicyServiceClient) DeleteRetryPolicy(ctx context.Context, in *RetryPolicyDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.RetryPolicyService/DeleteRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *retryPolicyServiceClient) GetRetryPolicy(ctx context.Context, in *RetryPolicyGetRequest, opts ...grpc.CallOption) (*RetryPolicy, error) { + out := new(RetryPolicy) + err := c.cc.Invoke(ctx, "/api.RetryPolicyService/GetRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *retryPolicyServiceClient) GetRetryPolicies(ctx context.Context, in *RetryPolicyListRequest, opts ...grpc.CallOption) (*RetryPolicyList, error) { + out := new(RetryPolicyList) + err := c.cc.Invoke(ctx, "/api.RetryPolicyService/GetRetryPolicies", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RetryPolicyServiceServer is the server API for RetryPolicyService service. +type RetryPolicyServiceServer interface { + CreateRetryPolicy(context.Context, *RetryPolicy) (*types.Empty, error) + UpdateRetryPolicy(context.Context, *RetryPolicy) (*types.Empty, error) + DeleteRetryPolicy(context.Context, *RetryPolicyDeleteRequest) (*types.Empty, error) + GetRetryPolicy(context.Context, *RetryPolicyGetRequest) (*RetryPolicy, error) + GetRetryPolicies(context.Context, *RetryPolicyListRequest) (*RetryPolicyList, error) +} + +// UnimplementedRetryPolicyServiceServer can be embedded to have forward compatible implementations. +type UnimplementedRetryPolicyServiceServer struct { +} + +func (*UnimplementedRetryPolicyServiceServer) CreateRetryPolicy(ctx context.Context, req *RetryPolicy) (*types.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateRetryPolicy not implemented") +} +func (*UnimplementedRetryPolicyServiceServer) UpdateRetryPolicy(ctx context.Context, req *RetryPolicy) (*types.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateRetryPolicy not implemented") +} +func (*UnimplementedRetryPolicyServiceServer) DeleteRetryPolicy(ctx context.Context, req *RetryPolicyDeleteRequest) (*types.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteRetryPolicy not implemented") +} +func (*UnimplementedRetryPolicyServiceServer) GetRetryPolicy(ctx context.Context, req *RetryPolicyGetRequest) (*RetryPolicy, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRetryPolicy not implemented") +} +func (*UnimplementedRetryPolicyServiceServer) GetRetryPolicies(ctx context.Context, req *RetryPolicyListRequest) (*RetryPolicyList, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRetryPolicies not implemented") +} + +func RegisterRetryPolicyServiceServer(s *grpc.Server, srv RetryPolicyServiceServer) { + s.RegisterService(&_RetryPolicyService_serviceDesc, srv) +} + +func _RetryPolicyService_CreateRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicy) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RetryPolicyServiceServer).CreateRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.RetryPolicyService/CreateRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RetryPolicyServiceServer).CreateRetryPolicy(ctx, req.(*RetryPolicy)) + } + return interceptor(ctx, in, info, handler) +} + +func _RetryPolicyService_UpdateRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicy) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RetryPolicyServiceServer).UpdateRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.RetryPolicyService/UpdateRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RetryPolicyServiceServer).UpdateRetryPolicy(ctx, req.(*RetryPolicy)) + } + return interceptor(ctx, in, info, handler) +} + +func _RetryPolicyService_DeleteRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicyDeleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RetryPolicyServiceServer).DeleteRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.RetryPolicyService/DeleteRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RetryPolicyServiceServer).DeleteRetryPolicy(ctx, req.(*RetryPolicyDeleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RetryPolicyService_GetRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicyGetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RetryPolicyServiceServer).GetRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.RetryPolicyService/GetRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RetryPolicyServiceServer).GetRetryPolicy(ctx, req.(*RetryPolicyGetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RetryPolicyService_GetRetryPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicyListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RetryPolicyServiceServer).GetRetryPolicies(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.RetryPolicyService/GetRetryPolicies", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RetryPolicyServiceServer).GetRetryPolicies(ctx, req.(*RetryPolicyListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _RetryPolicyService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "api.RetryPolicyService", + HandlerType: (*RetryPolicyServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateRetryPolicy", + Handler: _RetryPolicyService_CreateRetryPolicy_Handler, + }, + { + MethodName: "UpdateRetryPolicy", + Handler: _RetryPolicyService_UpdateRetryPolicy_Handler, + }, + { + MethodName: "DeleteRetryPolicy", + Handler: _RetryPolicyService_DeleteRetryPolicy_Handler, + }, + { + MethodName: "GetRetryPolicy", + Handler: _RetryPolicyService_GetRetryPolicy_Handler, + }, + { + MethodName: "GetRetryPolicies", + Handler: _RetryPolicyService_GetRetryPolicies_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pkg/api/submit.proto", +} + // SubmitClient is the client API for Submit service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. @@ -3114,6 +3821,11 @@ type SubmitClient interface { DeleteQueue(ctx context.Context, in *QueueDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) GetQueue(ctx context.Context, in *QueueGetRequest, opts ...grpc.CallOption) (*Queue, error) GetQueues(ctx context.Context, in *StreamingQueueGetRequest, opts ...grpc.CallOption) (Submit_GetQueuesClient, error) + CreateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) + UpdateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) + DeleteRetryPolicy(ctx context.Context, in *RetryPolicyDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) + GetRetryPolicy(ctx context.Context, in *RetryPolicyGetRequest, opts ...grpc.CallOption) (*RetryPolicy, error) + GetRetryPolicies(ctx context.Context, in *RetryPolicyListRequest, opts ...grpc.CallOption) (*RetryPolicyList, error) Health(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (*HealthCheckResponse, error) } @@ -3256,6 +3968,51 @@ func (x *submitGetQueuesClient) Recv() (*StreamingQueueMessage, error) { return m, nil } +func (c *submitClient) CreateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.Submit/CreateRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *submitClient) UpdateRetryPolicy(ctx context.Context, in *RetryPolicy, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.Submit/UpdateRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *submitClient) DeleteRetryPolicy(ctx context.Context, in *RetryPolicyDeleteRequest, opts ...grpc.CallOption) (*types.Empty, error) { + out := new(types.Empty) + err := c.cc.Invoke(ctx, "/api.Submit/DeleteRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *submitClient) GetRetryPolicy(ctx context.Context, in *RetryPolicyGetRequest, opts ...grpc.CallOption) (*RetryPolicy, error) { + out := new(RetryPolicy) + err := c.cc.Invoke(ctx, "/api.Submit/GetRetryPolicy", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *submitClient) GetRetryPolicies(ctx context.Context, in *RetryPolicyListRequest, opts ...grpc.CallOption) (*RetryPolicyList, error) { + out := new(RetryPolicyList) + err := c.cc.Invoke(ctx, "/api.Submit/GetRetryPolicies", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *submitClient) Health(ctx context.Context, in *types.Empty, opts ...grpc.CallOption) (*HealthCheckResponse, error) { out := new(HealthCheckResponse) err := c.cc.Invoke(ctx, "/api.Submit/Health", in, out, opts...) @@ -3279,6 +4036,11 @@ type SubmitServer interface { DeleteQueue(context.Context, *QueueDeleteRequest) (*types.Empty, error) GetQueue(context.Context, *QueueGetRequest) (*Queue, error) GetQueues(*StreamingQueueGetRequest, Submit_GetQueuesServer) error + CreateRetryPolicy(context.Context, *RetryPolicy) (*types.Empty, error) + UpdateRetryPolicy(context.Context, *RetryPolicy) (*types.Empty, error) + DeleteRetryPolicy(context.Context, *RetryPolicyDeleteRequest) (*types.Empty, error) + GetRetryPolicy(context.Context, *RetryPolicyGetRequest) (*RetryPolicy, error) + GetRetryPolicies(context.Context, *RetryPolicyListRequest) (*RetryPolicyList, error) Health(context.Context, *types.Empty) (*HealthCheckResponse, error) } @@ -3322,6 +4084,21 @@ func (*UnimplementedSubmitServer) GetQueue(ctx context.Context, req *QueueGetReq func (*UnimplementedSubmitServer) GetQueues(req *StreamingQueueGetRequest, srv Submit_GetQueuesServer) error { return status.Errorf(codes.Unimplemented, "method GetQueues not implemented") } +func (*UnimplementedSubmitServer) CreateRetryPolicy(ctx context.Context, req *RetryPolicy) (*types.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateRetryPolicy not implemented") +} +func (*UnimplementedSubmitServer) UpdateRetryPolicy(ctx context.Context, req *RetryPolicy) (*types.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateRetryPolicy not implemented") +} +func (*UnimplementedSubmitServer) DeleteRetryPolicy(ctx context.Context, req *RetryPolicyDeleteRequest) (*types.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteRetryPolicy not implemented") +} +func (*UnimplementedSubmitServer) GetRetryPolicy(ctx context.Context, req *RetryPolicyGetRequest) (*RetryPolicy, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRetryPolicy not implemented") +} +func (*UnimplementedSubmitServer) GetRetryPolicies(ctx context.Context, req *RetryPolicyListRequest) (*RetryPolicyList, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRetryPolicies not implemented") +} func (*UnimplementedSubmitServer) Health(ctx context.Context, req *types.Empty) (*HealthCheckResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Health not implemented") } @@ -3549,6 +4326,96 @@ func (x *submitGetQueuesServer) Send(m *StreamingQueueMessage) error { return x.ServerStream.SendMsg(m) } +func _Submit_CreateRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicy) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubmitServer).CreateRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Submit/CreateRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubmitServer).CreateRetryPolicy(ctx, req.(*RetryPolicy)) + } + return interceptor(ctx, in, info, handler) +} + +func _Submit_UpdateRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicy) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubmitServer).UpdateRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Submit/UpdateRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubmitServer).UpdateRetryPolicy(ctx, req.(*RetryPolicy)) + } + return interceptor(ctx, in, info, handler) +} + +func _Submit_DeleteRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicyDeleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubmitServer).DeleteRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Submit/DeleteRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubmitServer).DeleteRetryPolicy(ctx, req.(*RetryPolicyDeleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Submit_GetRetryPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicyGetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubmitServer).GetRetryPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Submit/GetRetryPolicy", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubmitServer).GetRetryPolicy(ctx, req.(*RetryPolicyGetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Submit_GetRetryPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RetryPolicyListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubmitServer).GetRetryPolicies(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/api.Submit/GetRetryPolicies", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubmitServer).GetRetryPolicies(ctx, req.(*RetryPolicyListRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Submit_Health_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(types.Empty) if err := dec(in); err != nil { @@ -3615,6 +4482,26 @@ var _Submit_serviceDesc = grpc.ServiceDesc{ MethodName: "GetQueue", Handler: _Submit_GetQueue_Handler, }, + { + MethodName: "CreateRetryPolicy", + Handler: _Submit_CreateRetryPolicy_Handler, + }, + { + MethodName: "UpdateRetryPolicy", + Handler: _Submit_UpdateRetryPolicy_Handler, + }, + { + MethodName: "DeleteRetryPolicy", + Handler: _Submit_DeleteRetryPolicy_Handler, + }, + { + MethodName: "GetRetryPolicy", + Handler: _Submit_GetRetryPolicy_Handler, + }, + { + MethodName: "GetRetryPolicies", + Handler: _Submit_GetRetryPolicies_Handler, + }, { MethodName: "Health", Handler: _Submit_Health_Handler, @@ -4661,6 +5548,13 @@ func (m *Queue) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.RetryPolicy) > 0 { + i -= len(m.RetryPolicy) + copy(dAtA[i:], m.RetryPolicy) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.RetryPolicy))) + i-- + dAtA[i] = 0x5a + } if len(m.Labels) > 0 { for k := range m.Labels { v := m.Labels[k] @@ -4982,7 +5876,319 @@ func (m *PriorityClassPoolResourceLimits) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } -func (m *QueueList) Marshal() (dAtA []byte, err error) { +func (m *QueueList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueueList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueueList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Queues) > 0 { + for iNdEx := len(m.Queues) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Queues[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSubmit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *CancellationResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CancellationResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CancellationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.CancelledIds) > 0 { + for iNdEx := len(m.CancelledIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.CancelledIds[iNdEx]) + copy(dAtA[i:], m.CancelledIds[iNdEx]) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.CancelledIds[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PreemptionResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PreemptionResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PreemptionResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PreemptionResults) > 0 { + for k := range m.PreemptionResults { + v := m.PreemptionResults[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarintSubmit(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintSubmit(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintSubmit(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *RetryPolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RetryPolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RetryPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Rules) > 0 { + for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSubmit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.DefaultAction != 0 { + i = encodeVarintSubmit(dAtA, i, uint64(m.DefaultAction)) + i-- + dAtA[i] = 0x18 + } + if m.RetryLimit != 0 { + i = encodeVarintSubmit(dAtA, i, uint64(m.RetryLimit)) + i-- + dAtA[i] = 0x10 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RetryRule) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RetryRule) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RetryRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.OnSubcategory) > 0 { + i -= len(m.OnSubcategory) + copy(dAtA[i:], m.OnSubcategory) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.OnSubcategory))) + i-- + dAtA[i] = 0x32 + } + if len(m.OnCategory) > 0 { + i -= len(m.OnCategory) + copy(dAtA[i:], m.OnCategory) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.OnCategory))) + i-- + dAtA[i] = 0x2a + } + if len(m.OnTerminationMessagePattern) > 0 { + i -= len(m.OnTerminationMessagePattern) + copy(dAtA[i:], m.OnTerminationMessagePattern) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.OnTerminationMessagePattern))) + i-- + dAtA[i] = 0x22 + } + if m.OnExitCodes != nil { + { + size, err := m.OnExitCodes.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSubmit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.OnConditions) > 0 { + for iNdEx := len(m.OnConditions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.OnConditions[iNdEx]) + copy(dAtA[i:], m.OnConditions[iNdEx]) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.OnConditions[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if m.Action != 0 { + i = encodeVarintSubmit(dAtA, i, uint64(m.Action)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RetryExitCodeMatcher) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RetryExitCodeMatcher) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RetryExitCodeMatcher) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Values) > 0 { + dAtA16 := make([]byte, len(m.Values)*10) + var j15 int + for _, num1 := range m.Values { + num := uint64(num1) + for num >= 1<<7 { + dAtA16[j15] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j15++ + } + dAtA16[j15] = uint8(num) + j15++ + } + i -= j15 + copy(dAtA[i:], dAtA16[:j15]) + i = encodeVarintSubmit(dAtA, i, uint64(j15)) + i-- + dAtA[i] = 0x12 + } + if m.Operator != 0 { + i = encodeVarintSubmit(dAtA, i, uint64(m.Operator)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RetryPolicyGetRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RetryPolicyGetRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RetryPolicyGetRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RetryPolicyDeleteRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -4992,34 +6198,27 @@ func (m *QueueList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueueList) MarshalTo(dAtA []byte) (int, error) { +func (m *RetryPolicyDeleteRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueueList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RetryPolicyDeleteRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Queues) > 0 { - for iNdEx := len(m.Queues) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Queues[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSubmit(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSubmit(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *CancellationResult) Marshal() (dAtA []byte, err error) { +func (m *RetryPolicyListRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -5029,29 +6228,20 @@ func (m *CancellationResult) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *CancellationResult) MarshalTo(dAtA []byte) (int, error) { +func (m *RetryPolicyListRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *CancellationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RetryPolicyListRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.CancelledIds) > 0 { - for iNdEx := len(m.CancelledIds) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.CancelledIds[iNdEx]) - copy(dAtA[i:], m.CancelledIds[iNdEx]) - i = encodeVarintSubmit(dAtA, i, uint64(len(m.CancelledIds[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } return len(dAtA) - i, nil } -func (m *PreemptionResult) Marshal() (dAtA []byte, err error) { +func (m *RetryPolicyList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -5061,31 +6251,26 @@ func (m *PreemptionResult) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PreemptionResult) MarshalTo(dAtA []byte) (int, error) { +func (m *RetryPolicyList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PreemptionResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RetryPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.PreemptionResults) > 0 { - for k := range m.PreemptionResults { - v := m.PreemptionResults[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarintSubmit(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarintSubmit(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarintSubmit(dAtA, i, uint64(baseI-i)) + if len(m.RetryPolicies) > 0 { + for iNdEx := len(m.RetryPolicies) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.RetryPolicies[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSubmit(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0xa } @@ -5614,20 +6799,20 @@ func (m *QueueCancelRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.JobStates) > 0 { - dAtA19 := make([]byte, len(m.JobStates)*10) - var j18 int + dAtA22 := make([]byte, len(m.JobStates)*10) + var j21 int for _, num := range m.JobStates { for num >= 1<<7 { - dAtA19[j18] = uint8(uint64(num)&0x7f | 0x80) + dAtA22[j21] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j18++ + j21++ } - dAtA19[j18] = uint8(num) - j18++ + dAtA22[j21] = uint8(num) + j21++ } - i -= j18 - copy(dAtA[i:], dAtA19[:j18]) - i = encodeVarintSubmit(dAtA, i, uint64(j18)) + i -= j21 + copy(dAtA[i:], dAtA22[:j21]) + i = encodeVarintSubmit(dAtA, i, uint64(j21)) i-- dAtA[i] = 0x1a } @@ -6177,6 +7362,10 @@ func (m *Queue) Size() (n int) { n += mapEntrySize + 1 + sovSubmit(uint64(mapEntrySize)) } } + l = len(m.RetryPolicy) + if l > 0 { + n += 1 + l + sovSubmit(uint64(l)) + } return n } @@ -6312,6 +7501,134 @@ func (m *PreemptionResult) Size() (n int) { return n } +func (m *RetryPolicy) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSubmit(uint64(l)) + } + if m.RetryLimit != 0 { + n += 1 + sovSubmit(uint64(m.RetryLimit)) + } + if m.DefaultAction != 0 { + n += 1 + sovSubmit(uint64(m.DefaultAction)) + } + if len(m.Rules) > 0 { + for _, e := range m.Rules { + l = e.Size() + n += 1 + l + sovSubmit(uint64(l)) + } + } + return n +} + +func (m *RetryRule) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Action != 0 { + n += 1 + sovSubmit(uint64(m.Action)) + } + if len(m.OnConditions) > 0 { + for _, s := range m.OnConditions { + l = len(s) + n += 1 + l + sovSubmit(uint64(l)) + } + } + if m.OnExitCodes != nil { + l = m.OnExitCodes.Size() + n += 1 + l + sovSubmit(uint64(l)) + } + l = len(m.OnTerminationMessagePattern) + if l > 0 { + n += 1 + l + sovSubmit(uint64(l)) + } + l = len(m.OnCategory) + if l > 0 { + n += 1 + l + sovSubmit(uint64(l)) + } + l = len(m.OnSubcategory) + if l > 0 { + n += 1 + l + sovSubmit(uint64(l)) + } + return n +} + +func (m *RetryExitCodeMatcher) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Operator != 0 { + n += 1 + sovSubmit(uint64(m.Operator)) + } + if len(m.Values) > 0 { + l = 0 + for _, e := range m.Values { + l += sovSubmit(uint64(e)) + } + n += 1 + sovSubmit(uint64(l)) + l + } + return n +} + +func (m *RetryPolicyGetRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSubmit(uint64(l)) + } + return n +} + +func (m *RetryPolicyDeleteRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSubmit(uint64(l)) + } + return n +} + +func (m *RetryPolicyListRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *RetryPolicyList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.RetryPolicies) > 0 { + for _, e := range m.RetryPolicies { + l = e.Size() + n += 1 + l + sovSubmit(uint64(l)) + } + } + return n +} + func (m *QueueGetRequest) Size() (n int) { if m == nil { return 0 @@ -6580,36 +7897,104 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JobSubmitRequestItem: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JobSubmitRequestItem: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.Priority = float64(math.Float64frombits(v)) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodSpec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PodSpec == nil { + m.PodSpec = &v1.PodSpec{} + } + if err := m.PodSpec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JobSubmitRequestItem: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JobSubmitRequestItem: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit } - var v uint64 - if (iNdEx + 8) > l { + if postIndex > l { return io.ErrUnexpectedEOF } - v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - m.Priority = float64(math.Float64frombits(v)) - case 2: + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSpec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6636,18 +8021,109 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.PodSpec == nil { - m.PodSpec = &v1.PodSpec{} + if m.Labels == nil { + m.Labels = make(map[string]string) } - if err := m.PodSpec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } + m.Labels[mapkey] = mapvalue iNdEx = postIndex - case 3: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -6657,27 +8133,122 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Namespace = string(dAtA[iNdEx:postIndex]) + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Annotations == nil { + m.Annotations = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Annotations[mapkey] = mapvalue iNdEx = postIndex - case 4: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RequiredNodeLabels", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6704,8 +8275,8 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Labels == nil { - m.Labels = make(map[string]string) + if m.RequiredNodeLabels == nil { + m.RequiredNodeLabels = make(map[string]string) } var mapkey string var mapvalue string @@ -6800,11 +8371,11 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.Labels[mapkey] = mapvalue + m.RequiredNodeLabels[mapkey] = mapvalue iNdEx = postIndex - case 5: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PodSpecs", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6831,14 +8402,247 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Annotations == nil { - m.Annotations = make(map[string]string) + m.PodSpecs = append(m.PodSpecs, &v1.PodSpec{}) + if err := m.PodSpecs[len(m.PodSpecs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ingress = append(m.Ingress, &IngressConfig{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Services", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Services = append(m.Services, &ServiceConfig{}) + if err := m.Services[len(m.Services)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scheduler", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Scheduler = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExternalJobUri", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExternalJobUri = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressConfig) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= IngressType(b&0x7F) << shift + if b < 0x80 { + break + } } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 + case 2: + if wireType == 0 { + var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -6848,43 +8652,51 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - wire |= uint64(b&0x7F) << shift + v |= uint32(b&0x7F) << shift if b < 0x80 { break } } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + m.Ports = append(m.Ports, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit + if iNdEx >= l { + return io.ErrUnexpectedEOF } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF + } + if packedLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 + } + elementCount = count + if elementCount != 0 && len(m.Ports) == 0 { + m.Ports = make([]uint32, 0, elementCount) + } + for iNdEx < postIndex { + var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -6894,44 +8706,19 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift + v |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy + m.Ports = append(m.Ports, v) } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) } - m.Annotations[mapkey] = mapvalue - iNdEx = postIndex - case 6: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RequiredNodeLabels", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6958,8 +8745,8 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RequiredNodeLabels == nil { - m.RequiredNodeLabels = make(map[string]string) + if m.Annotations == nil { + m.Annotations = make(map[string]string) } var mapkey string var mapvalue string @@ -7054,113 +8841,13 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.RequiredNodeLabels[mapkey] = mapvalue - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSpecs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PodSpecs = append(m.PodSpecs, &v1.PodSpec{}) - if err := m.PodSpecs[len(m.PodSpecs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClientId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ingress = append(m.Ingress, &IngressConfig{}) - if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Annotations[mapkey] = mapvalue iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Services", wireType) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TlsEnabled", wireType) } - var msglen int + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -7168,31 +8855,17 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Services = append(m.Services, &ServiceConfig{}) - if err := m.Services[len(m.Services)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } } - iNdEx = postIndex - case 11: + m.TlsEnabled = bool(v != 0) + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scheduler", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CertName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -7220,13 +8893,13 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Scheduler = string(dAtA[iNdEx:postIndex]) + m.CertName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 13: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExternalJobUri", wireType) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UseClusterIP", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -7236,24 +8909,12 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ExternalJobUri = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex + m.UseClusterIP = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSubmit(dAtA[iNdEx:]) @@ -7275,7 +8936,7 @@ func (m *JobSubmitRequestItem) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressConfig) Unmarshal(dAtA []byte) error { +func (m *ServiceConfig) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -7298,10 +8959,10 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressConfig: wiretype end group for non-group") + return fmt.Errorf("proto: ServiceConfig: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressConfig: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ServiceConfig: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -7318,7 +8979,7 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Type |= IngressType(b&0x7F) << shift + m.Type |= ServiceType(b&0x7F) << shift if b < 0x80 { break } @@ -7401,9 +9062,9 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { } case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -7413,124 +9074,79 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Annotations == nil { - m.Annotations = make(map[string]string) + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit } - m.Annotations[mapkey] = mapvalue - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TlsEnabled", wireType) + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - var v int + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JobSubmitRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JobSubmitRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) + } + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -7540,15 +9156,27 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.TlsEnabled = bool(v != 0) - case 5: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Queue = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -7576,13 +9204,13 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CertName = string(dAtA[iNdEx:postIndex]) + m.JobSetId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UseClusterIP", wireType) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JobRequestItems", wireType) } - var v int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -7592,12 +9220,26 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - m.UseClusterIP = bool(v != 0) + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JobRequestItems = append(m.JobRequestItems, &JobSubmitRequestItem{}) + if err := m.JobRequestItems[len(m.JobRequestItems)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSubmit(dAtA[iNdEx:]) @@ -7619,7 +9261,7 @@ func (m *IngressConfig) Unmarshal(dAtA []byte) error { } return nil } -func (m *ServiceConfig) Unmarshal(dAtA []byte) error { +func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -7642,17 +9284,17 @@ func (m *ServiceConfig) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ServiceConfig: wiretype end group for non-group") + return fmt.Errorf("proto: JobPreemptRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ServiceConfig: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: JobPreemptRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) } - m.Type = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -7662,90 +9304,91 @@ func (m *ServiceConfig) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Type |= ServiceType(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Queue = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 2: - if wireType == 0 { - var v uint32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit } - m.Ports = append(m.Ports, v) - } else if wireType == 2 { - var packedLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - packedLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + if iNdEx >= l { + return io.ErrUnexpectedEOF } - if packedLen < 0 { - return ErrInvalidLengthSubmit + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - postIndex := iNdEx + packedLen - if postIndex < 0 { - return ErrInvalidLengthSubmit + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JobSetId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JobIds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit } - if postIndex > l { + if iNdEx >= l { return io.ErrUnexpectedEOF } - var elementCount int - var count int - for _, integer := range dAtA[iNdEx:postIndex] { - if integer < 128 { - count++ - } - } - elementCount = count - if elementCount != 0 && len(m.Ports) == 0 { - m.Ports = make([]uint32, 0, elementCount) - } - for iNdEx < postIndex { - var v uint32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Ports = append(m.Ports, v) + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - } else { - return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) } - case 3: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JobIds = append(m.JobIds, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -7773,7 +9416,7 @@ func (m *ServiceConfig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -7796,7 +9439,7 @@ func (m *ServiceConfig) Unmarshal(dAtA []byte) error { } return nil } -func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error { +func (m *JobCancelRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -7819,15 +9462,15 @@ func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JobSubmitRequest: wiretype end group for non-group") + return fmt.Errorf("proto: JobCancelRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JobSubmitRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: JobCancelRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JobId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -7855,7 +9498,7 @@ func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Queue = string(dAtA[iNdEx:postIndex]) + m.JobId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -7891,9 +9534,9 @@ func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobRequestItems", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -7903,25 +9546,87 @@ func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobRequestItems = append(m.JobRequestItems, &JobSubmitRequestItem{}) - if err := m.JobRequestItems[len(m.JobRequestItems)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.Queue = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JobIds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JobIds = append(m.JobIds, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -7944,7 +9649,7 @@ func (m *JobSubmitRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error { +func (m *JobSetCancelRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -7967,15 +9672,15 @@ func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JobPreemptRequest: wiretype end group for non-group") + return fmt.Errorf("proto: JobSetCancelRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JobPreemptRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: JobSetCancelRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8003,11 +9708,11 @@ func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Queue = string(dAtA[iNdEx:postIndex]) + m.JobSetId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8035,13 +9740,13 @@ func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.JobSetId = string(dAtA[iNdEx:postIndex]) + m.Queue = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -8051,23 +9756,27 @@ func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobIds = append(m.JobIds, string(dAtA[iNdEx:postIndex])) + if m.Filter == nil { + m.Filter = &JobSetFilter{} + } + if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 4: if wireType != 2 { @@ -8122,7 +9831,7 @@ func (m *JobPreemptRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *JobCancelRequest) Unmarshal(dAtA []byte) error { +func (m *JobSetFilter) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8145,15 +9854,134 @@ func (m *JobCancelRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JobCancelRequest: wiretype end group for non-group") + return fmt.Errorf("proto: JobSetFilter: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JobCancelRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: JobSetFilter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType == 0 { + var v JobState + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= JobState(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.States = append(m.States, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + if elementCount != 0 && len(m.States) == 0 { + m.States = make([]JobState, 0, elementCount) + } + for iNdEx < postIndex { + var v JobState + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= JobState(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.States = append(m.States, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field States", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Job) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Job: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Job: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8181,7 +10009,7 @@ func (m *JobCancelRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.JobId = string(dAtA[iNdEx:postIndex]) + m.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -8248,10 +10076,21 @@ func (m *JobCancelRequest) Unmarshal(dAtA []byte) error { m.Queue = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.Priority = float64(math.Float64frombits(v)) + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PodSpec", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -8261,29 +10100,33 @@ func (m *JobCancelRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobIds = append(m.JobIds, string(dAtA[iNdEx:postIndex])) + if m.PodSpec == nil { + m.PodSpec = &v1.PodSpec{} + } + if err := m.PodSpec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 5: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Created", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -8293,77 +10136,63 @@ func (m *JobCancelRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.Reason = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { + if m.Created == nil { + m.Created = &types.Timestamp{} + } + if err := m.Created.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *JobSetCancelRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit } - if iNdEx >= l { - return io.ErrUnexpectedEOF + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if postIndex > l { + return io.ErrUnexpectedEOF } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JobSetCancelRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JobSetCancelRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8391,13 +10220,13 @@ func (m *JobSetCancelRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.JobSetId = string(dAtA[iNdEx:postIndex]) + m.Owner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -8407,27 +10236,249 @@ func (m *JobSetCancelRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Labels == nil { + m.Labels = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Labels[mapkey] = mapvalue + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.Queue = string(dAtA[iNdEx:postIndex]) + if m.Annotations == nil { + m.Annotations = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Annotations[mapkey] = mapvalue iNdEx = postIndex - case 3: + case 11: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RequiredNodeLabels", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8454,98 +10505,14 @@ func (m *JobSetCancelRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Filter == nil { - m.Filter = &JobSetFilter{} - } - if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Reason = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *JobSetFilter) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if m.RequiredNodeLabels == nil { + m.RequiredNodeLabels = make(map[string]string) } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JobSetFilter: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JobSetFilter: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType == 0 { - var v JobState + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -8555,44 +10522,43 @@ func (m *JobSetFilter) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= JobState(b&0x7F) << shift + wire |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.States = append(m.States, v) - } else if wireType == 2 { - var packedLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { - return io.ErrUnexpectedEOF + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit } - b := dAtA[iNdEx] - iNdEx++ - packedLen |= int(b&0x7F) << shift - if b < 0x80 { - break + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit } - } - if packedLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + packedLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var elementCount int - if elementCount != 0 && len(m.States) == 0 { - m.States = make([]JobState, 0, elementCount) - } - for iNdEx < postIndex { - var v JobState + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -8602,69 +10568,78 @@ func (m *JobSetFilter) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= JobState(b&0x7F) << shift + stringLenmapvalue |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.States = append(m.States, v) + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy } - } else { - return fmt.Errorf("proto: wrong wireType = %d for field States", wireType) - } - default: - iNdEx = preIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + m.RequiredNodeLabels[mapkey] = mapvalue + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodSpecs", wireType) } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Job) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } } - if iNdEx >= l { - return io.ErrUnexpectedEOF + if msglen < 0 { + return ErrInvalidLengthSubmit } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Job: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Job: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PodSpecs = append(m.PodSpecs, &v1.PodSpec{}) + if err := m.PodSpecs[len(m.PodSpecs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8692,13 +10667,13 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Id = string(dAtA[iNdEx:postIndex]) + m.ClientId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 14: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -8708,27 +10683,29 @@ func (m *Job) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobSetId = string(dAtA[iNdEx:postIndex]) + m.Ingress = append(m.Ingress, &IngressConfig{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 3: + case 15: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field QueueOwnershipUserGroups", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8756,22 +10733,45 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Queue = string(dAtA[iNdEx:postIndex]) + m.QueueOwnershipUserGroups = append(m.QueueOwnershipUserGroups, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 4: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Services", wireType) } - var v uint64 - if (iNdEx + 8) > l { + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { return io.ErrUnexpectedEOF } - v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - m.Priority = float64(math.Float64frombits(v)) - case 5: + m.Services = append(m.Services, &ServiceConfig{}) + if err := m.Services[len(m.Services)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 17: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSpec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field K8SIngress", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8798,16 +10798,114 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.PodSpec == nil { - m.PodSpec = &v1.PodSpec{} + m.K8SIngress = append(m.K8SIngress, &v11.Ingress{}) + if err := m.K8SIngress[len(m.K8SIngress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - if err := m.PodSpec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + iNdEx = postIndex + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field K8SService", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.K8SService = append(m.K8SService, &v1.Service{}) + if err := m.K8SService[len(m.K8SService)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 6: + case 19: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Created", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CompressedQueueOwnershipUserGroups", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CompressedQueueOwnershipUserGroups = append(m.CompressedQueueOwnershipUserGroups[:0], dAtA[iNdEx:postIndex]...) + if m.CompressedQueueOwnershipUserGroups == nil { + m.CompressedQueueOwnershipUserGroups = []byte{} + } + iNdEx = postIndex + case 20: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scheduler", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Scheduler = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SchedulingResourceRequirements", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8834,16 +10932,66 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Created == nil { - m.Created = &types.Timestamp{} + if m.SchedulingResourceRequirements == nil { + m.SchedulingResourceRequirements = &v1.ResourceRequirements{} } - if err := m.Created.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.SchedulingResourceRequirements.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 7: + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JobReprioritizeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JobReprioritizeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JobReprioritizeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JobIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8871,11 +11019,11 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Namespace = string(dAtA[iNdEx:postIndex]) + m.JobIds = append(m.JobIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 8: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8903,140 +11051,13 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Owner = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Labels == nil { - m.Labels = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Labels[mapkey] = mapvalue + m.JobSetId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 10: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Annotations", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -9044,124 +11065,90 @@ func (m *Job) Unmarshal(dAtA []byte) error { if iNdEx >= l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Annotations == nil { - m.Annotations = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - m.Annotations[mapkey] = mapvalue + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Queue = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 11: + case 4: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field NewPriority", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.NewPriority = float64(math.Float64frombits(v)) + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JobReprioritizeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JobReprioritizeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JobReprioritizeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RequiredNodeLabels", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ReprioritizationResults", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9188,8 +11175,8 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.RequiredNodeLabels == nil { - m.RequiredNodeLabels = make(map[string]string) + if m.ReprioritizationResults == nil { + m.ReprioritizationResults = make(map[string]string) } var mapkey string var mapvalue string @@ -9284,45 +11271,61 @@ func (m *Job) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.RequiredNodeLabels[mapkey] = mapvalue + m.ReprioritizationResults[mapkey] = mapvalue iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSpecs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err } - if msglen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JobSubmitResponseItem) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.PodSpecs = append(m.PodSpecs, &v1.PodSpec{}) - if err := m.PodSpecs[len(m.PodSpecs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex - case 13: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JobSubmitResponseItem: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JobSubmitResponseItem: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JobId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9350,13 +11353,13 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ClientId = string(dAtA[iNdEx:postIndex]) + m.JobId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 14: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -9366,61 +11369,77 @@ func (m *Job) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ingress = append(m.Ingress, &IngressConfig{}) - if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Error = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 15: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field QueueOwnershipUserGroups", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err } - intStringLen := int(stringLen) - if intStringLen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *JobSubmitResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.QueueOwnershipUserGroups = append(m.QueueOwnershipUserGroups, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 16: + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: JobSubmitResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: JobSubmitResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Services", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JobResponseItems", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9447,50 +11466,66 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Services = append(m.Services, &ServiceConfig{}) - if err := m.Services[len(m.Services)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.JobResponseItems = append(m.JobResponseItems, &JobSubmitResponseItem{}) + if err := m.JobResponseItems[len(m.JobResponseItems)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 17: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field K8SIngress", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err } - if msglen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Queue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.K8SIngress = append(m.K8SIngress, &v11.Ingress{}) - if err := m.K8SIngress[len(m.K8SIngress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex - case 18: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Queue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Queue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field K8SService", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -9500,31 +11535,40 @@ func (m *Job) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.K8SService = append(m.K8SService, &v1.Service{}) - if err := m.K8SService[len(m.K8SService)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 19: + case 2: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field PriorityFactor", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.PriorityFactor = float64(math.Float64frombits(v)) + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CompressedQueueOwnershipUserGroups", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserOwners", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -9534,29 +11578,27 @@ func (m *Job) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.CompressedQueueOwnershipUserGroups = append(m.CompressedQueueOwnershipUserGroups[:0], dAtA[iNdEx:postIndex]...) - if m.CompressedQueueOwnershipUserGroups == nil { - m.CompressedQueueOwnershipUserGroups = []byte{} - } + m.UserOwners = append(m.UserOwners, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 20: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scheduler", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GroupOwners", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9584,11 +11626,11 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Scheduler = string(dAtA[iNdEx:postIndex]) + m.GroupOwners = append(m.GroupOwners, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 21: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SchedulingResourceRequirements", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceLimits", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9615,68 +11657,88 @@ func (m *Job) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.SchedulingResourceRequirements == nil { - m.SchedulingResourceRequirements = &v1.ResourceRequirements{} - } - if err := m.SchedulingResourceRequirements.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *JobReprioritizeRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if m.ResourceLimits == nil { + m.ResourceLimits = make(map[string]float64) } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JobReprioritizeRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JobReprioritizeRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + var mapkey string + var mapvalue float64 + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapvaluetemp uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + mapvaluetemp = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + mapvalue = math.Float64frombits(mapvaluetemp) + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.ResourceLimits[mapkey] = mapvalue + iNdEx = postIndex + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -9686,29 +11748,31 @@ func (m *JobReprioritizeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobIds = append(m.JobIds, string(dAtA[iNdEx:postIndex])) + m.Permissions = append(m.Permissions, &Queue_Permissions{}) + if err := m.Permissions[len(m.Permissions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 2: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobSetId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceLimitsByPriorityClassName", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -9718,27 +11782,144 @@ func (m *JobReprioritizeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobSetId = string(dAtA[iNdEx:postIndex]) + if m.ResourceLimitsByPriorityClassName == nil { + m.ResourceLimitsByPriorityClassName = make(map[string]*PriorityClassResourceLimits) + } + var mapkey string + var mapvalue *PriorityClassResourceLimits + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthSubmit + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthSubmit + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &PriorityClassResourceLimits{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.ResourceLimitsByPriorityClassName[mapkey] = mapvalue iNdEx = postIndex - case 3: + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Cordoned", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Cordoned = bool(v != 0) + case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Queue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LabelsDeprecated", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -9766,72 +11947,11 @@ func (m *JobReprioritizeRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Queue = string(dAtA[iNdEx:postIndex]) + m.LabelsDeprecated = append(m.LabelsDeprecated, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 4: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field NewPriority", wireType) - } - var v uint64 - if (iNdEx + 8) > l { - return io.ErrUnexpectedEOF - } - v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - m.NewPriority = float64(math.Float64frombits(v)) - default: - iNdEx = preIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *JobReprioritizeResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: JobReprioritizeResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JobReprioritizeResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ReprioritizationResults", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9858,8 +11978,8 @@ func (m *JobReprioritizeResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ReprioritizationResults == nil { - m.ReprioritizationResults = make(map[string]string) + if m.Labels == nil { + m.Labels = make(map[string]string) } var mapkey string var mapvalue string @@ -9954,7 +12074,39 @@ func (m *JobReprioritizeResponse) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.ReprioritizationResults[mapkey] = mapvalue + m.Labels[mapkey] = mapvalue + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RetryPolicy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RetryPolicy = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -9977,7 +12129,7 @@ func (m *JobReprioritizeResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *JobSubmitResponseItem) Unmarshal(dAtA []byte) error { +func (m *Queue_Permissions) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10000,17 +12152,17 @@ func (m *JobSubmitResponseItem) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JobSubmitResponseItem: wiretype end group for non-group") + return fmt.Errorf("proto: Permissions: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JobSubmitResponseItem: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Permissions: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Subjects", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -10020,27 +12172,29 @@ func (m *JobSubmitResponseItem) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobId = string(dAtA[iNdEx:postIndex]) + m.Subjects = append(m.Subjects, &Queue_Permissions_Subject{}) + if err := m.Subjects[len(m.Subjects)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Verbs", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10068,7 +12222,7 @@ func (m *JobSubmitResponseItem) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Error = string(dAtA[iNdEx:postIndex]) + m.Verbs = append(m.Verbs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -10091,7 +12245,7 @@ func (m *JobSubmitResponseItem) Unmarshal(dAtA []byte) error { } return nil } -func (m *JobSubmitResponse) Unmarshal(dAtA []byte) error { +func (m *Queue_Permissions_Subject) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10114,17 +12268,17 @@ func (m *JobSubmitResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: JobSubmitResponse: wiretype end group for non-group") + return fmt.Errorf("proto: Subject: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: JobSubmitResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Subject: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JobResponseItems", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -10134,25 +12288,55 @@ func (m *JobSubmitResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.JobResponseItems = append(m.JobResponseItems, &JobSubmitResponseItem{}) - if err := m.JobResponseItems[len(m.JobResponseItems)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -10175,7 +12359,7 @@ func (m *JobSubmitResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *Queue) Unmarshal(dAtA []byte) error { +func (m *PriorityClassResourceLimits) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10198,60 +12382,17 @@ func (m *Queue) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Queue: wiretype end group for non-group") + return fmt.Errorf("proto: PriorityClassResourceLimits: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Queue: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PriorityClassResourceLimits: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field PriorityFactor", wireType) - } - var v uint64 - if (iNdEx + 8) > l { - return io.ErrUnexpectedEOF - } - v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - m.PriorityFactor = float64(math.Float64frombits(v)) - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserOwners", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaximumResourceFraction", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -10261,59 +12402,101 @@ func (m *Queue) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.UserOwners = append(m.UserOwners, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupOwners", wireType) + if m.MaximumResourceFraction == nil { + m.MaximumResourceFraction = make(map[string]float64) } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF + var mapkey string + var mapvalue float64 + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthSubmit + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthSubmit + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapvaluetemp uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + mapvaluetemp = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + mapvalue = math.Float64frombits(mapvaluetemp) + } else { + iNdEx = entryPreIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GroupOwners = append(m.GroupOwners, string(dAtA[iNdEx:postIndex])) + m.MaximumResourceFraction[mapkey] = mapvalue iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceLimits", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaximumResourceFractionByPool", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10340,11 +12523,11 @@ func (m *Queue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ResourceLimits == nil { - m.ResourceLimits = make(map[string]float64) + if m.MaximumResourceFractionByPool == nil { + m.MaximumResourceFractionByPool = make(map[string]*PriorityClassPoolResourceLimits) } var mapkey string - var mapvalue float64 + var mapvalue *PriorityClassPoolResourceLimits for iNdEx < postIndex { entryPreIndex := iNdEx var wire uint64 @@ -10393,13 +12576,36 @@ func (m *Queue) Unmarshal(dAtA []byte) error { mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) iNdEx = postStringIndexmapkey } else if fieldNum == 2 { - var mapvaluetemp uint64 - if (iNdEx + 8) > l { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthSubmit + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthSubmit + } + if postmsgIndex > l { return io.ErrUnexpectedEOF } - mapvaluetemp = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - mapvalue = math.Float64frombits(mapvaluetemp) + mapvalue = &PriorityClassPoolResourceLimits{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex } else { iNdEx = entryPreIndex skippy, err := skipSubmit(dAtA[iNdEx:]) @@ -10415,45 +12621,61 @@ func (m *Queue) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.ResourceLimits[mapkey] = mapvalue + m.MaximumResourceFractionByPool[mapkey] = mapvalue iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err } - if msglen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriorityClassPoolResourceLimits) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.Permissions = append(m.Permissions, &Queue_Permissions{}) - if err := m.Permissions[len(m.Permissions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex - case 7: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PriorityClassPoolResourceLimits: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriorityClassPoolResourceLimits: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceLimitsByPriorityClassName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaximumResourceFraction", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10480,11 +12702,11 @@ func (m *Queue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ResourceLimitsByPriorityClassName == nil { - m.ResourceLimitsByPriorityClassName = make(map[string]*PriorityClassResourceLimits) + if m.MaximumResourceFraction == nil { + m.MaximumResourceFraction = make(map[string]float64) } var mapkey string - var mapvalue *PriorityClassResourceLimits + var mapvalue float64 for iNdEx < postIndex { entryPreIndex := iNdEx var wire uint64 @@ -10533,36 +12755,13 @@ func (m *Queue) Unmarshal(dAtA []byte) error { mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) iNdEx = postStringIndexmapkey } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthSubmit - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthSubmit - } - if postmsgIndex > l { + var mapvaluetemp uint64 + if (iNdEx + 8) > l { return io.ErrUnexpectedEOF } - mapvalue = &PriorityClassResourceLimits{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex + mapvaluetemp = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + mapvalue = math.Float64frombits(mapvaluetemp) } else { iNdEx = entryPreIndex skippy, err := skipSubmit(dAtA[iNdEx:]) @@ -10578,13 +12777,63 @@ func (m *Queue) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.ResourceLimitsByPriorityClassName[mapkey] = mapvalue + m.MaximumResourceFraction[mapkey] = mapvalue iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Cordoned", wireType) + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err } - var v int + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueueList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueueList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueueList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Queues", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -10594,15 +12843,79 @@ func (m *Queue) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - m.Cordoned = bool(v != 0) - case 9: + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Queues = append(m.Queues, &Queue{}) + if err := m.Queues[len(m.Queues)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CancellationResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CancellationResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CancellationResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LabelsDeprecated", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CancelledIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10630,11 +12943,61 @@ func (m *Queue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.LabelsDeprecated = append(m.LabelsDeprecated, string(dAtA[iNdEx:postIndex])) + m.CancelledIds = append(m.CancelledIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 10: + default: + iNdEx = preIndex + skippy, err := skipSubmit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubmit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PreemptionResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PreemptionResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PreemptionResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreemptionResults", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10661,8 +13024,8 @@ func (m *Queue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Labels == nil { - m.Labels = make(map[string]string) + if m.PreemptionResults == nil { + m.PreemptionResults = make(map[string]string) } var mapkey string var mapvalue string @@ -10757,7 +13120,7 @@ func (m *Queue) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.Labels[mapkey] = mapvalue + m.PreemptionResults[mapkey] = mapvalue iNdEx = postIndex default: iNdEx = preIndex @@ -10780,7 +13143,7 @@ func (m *Queue) Unmarshal(dAtA []byte) error { } return nil } -func (m *Queue_Permissions) Unmarshal(dAtA []byte) error { +func (m *RetryPolicy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10803,17 +13166,17 @@ func (m *Queue_Permissions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Permissions: wiretype end group for non-group") + return fmt.Errorf("proto: RetryPolicy: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Permissions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RetryPolicy: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subjects", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -10823,31 +13186,67 @@ func (m *Queue_Permissions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.Subjects = append(m.Subjects, &Queue_Permissions_Subject{}) - if err := m.Subjects[len(m.Subjects)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RetryLimit", wireType) + } + m.RetryLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RetryLimit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultAction", wireType) + } + m.DefaultAction = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DefaultAction |= RetryAction(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Verbs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -10857,23 +13256,25 @@ func (m *Queue_Permissions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.Verbs = append(m.Verbs, string(dAtA[iNdEx:postIndex])) + m.Rules = append(m.Rules, &RetryRule{}) + if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -10896,7 +13297,7 @@ func (m *Queue_Permissions) Unmarshal(dAtA []byte) error { } return nil } -func (m *Queue_Permissions_Subject) Unmarshal(dAtA []byte) error { +func (m *RetryRule) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10906,28 +13307,147 @@ func (m *Queue_Permissions_Subject) Unmarshal(dAtA []byte) error { if shift >= 64 { return ErrIntOverflowSubmit } - if iNdEx >= l { - return io.ErrUnexpectedEOF + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RetryRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RetryRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + m.Action = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Action |= RetryAction(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OnConditions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OnConditions = append(m.OnConditions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OnExitCodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.OnExitCodes == nil { + m.OnExitCodes = &RetryExitCodeMatcher{} + } + if err := m.OnExitCodes.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OnTerminationMessagePattern", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubmit + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubmit } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubmit } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Subject: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Subject: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OnTerminationMessagePattern = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OnCategory", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10955,11 +13475,11 @@ func (m *Queue_Permissions_Subject) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Kind = string(dAtA[iNdEx:postIndex]) + m.OnCategory = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field OnSubcategory", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10987,7 +13507,7 @@ func (m *Queue_Permissions_Subject) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.OnSubcategory = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -11010,7 +13530,7 @@ func (m *Queue_Permissions_Subject) Unmarshal(dAtA []byte) error { } return nil } -func (m *PriorityClassResourceLimits) Unmarshal(dAtA []byte) error { +func (m *RetryExitCodeMatcher) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11033,17 +13553,17 @@ func (m *PriorityClassResourceLimits) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PriorityClassResourceLimits: wiretype end group for non-group") + return fmt.Errorf("proto: RetryExitCodeMatcher: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PriorityClassResourceLimits: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RetryExitCodeMatcher: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaximumResourceFraction", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType) } - var msglen int + m.Operator = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -11053,29 +13573,14 @@ func (m *PriorityClassResourceLimits) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.Operator |= ExitCodeOperator(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.MaximumResourceFraction == nil { - m.MaximumResourceFraction = make(map[string]float64) - } - var mapkey string - var mapvalue float64 - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 + case 2: + if wireType == 0 { + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -11085,103 +13590,14 @@ func (m *PriorityClassResourceLimits) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - wire |= uint64(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapvaluetemp uint64 - if (iNdEx + 8) > l { - return io.ErrUnexpectedEOF - } - mapvaluetemp = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - mapvalue = math.Float64frombits(mapvaluetemp) - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.MaximumResourceFraction[mapkey] = mapvalue - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaximumResourceFractionByPool", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.MaximumResourceFractionByPool == nil { - m.MaximumResourceFractionByPool = make(map[string]*PriorityClassPoolResourceLimits) - } - var mapkey string - var mapvalue *PriorityClassPoolResourceLimits - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 + m.Values = append(m.Values, v) + } else if wireType == 2 { + var packedLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -11191,89 +13607,53 @@ func (m *PriorityClassResourceLimits) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - wire |= uint64(b&0x7F) << shift + packedLen |= int(b&0x7F) << shift if b < 0x80 { break } } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF + if packedLen < 0 { + return ErrInvalidLengthSubmit + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthSubmit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int + } + elementCount = count + if elementCount != 0 && len(m.Values) == 0 { + m.Values = make([]int32, 0, elementCount) + } + for iNdEx < postIndex { + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit } if iNdEx >= l { return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthSubmit - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthSubmit - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &PriorityClassPoolResourceLimits{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } } - iNdEx += skippy + m.Values = append(m.Values, v) } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Values", wireType) } - m.MaximumResourceFractionByPool[mapkey] = mapvalue - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSubmit(dAtA[iNdEx:]) @@ -11295,7 +13675,7 @@ func (m *PriorityClassResourceLimits) Unmarshal(dAtA []byte) error { } return nil } -func (m *PriorityClassPoolResourceLimits) Unmarshal(dAtA []byte) error { +func (m *RetryPolicyGetRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11318,17 +13698,17 @@ func (m *PriorityClassPoolResourceLimits) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PriorityClassPoolResourceLimits: wiretype end group for non-group") + return fmt.Errorf("proto: RetryPolicyGetRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PriorityClassPoolResourceLimits: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RetryPolicyGetRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaximumResourceFraction", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -11338,97 +13718,23 @@ func (m *PriorityClassPoolResourceLimits) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - if m.MaximumResourceFraction == nil { - m.MaximumResourceFraction = make(map[string]float64) - } - var mapkey string - var mapvalue float64 - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapvaluetemp uint64 - if (iNdEx + 8) > l { - return io.ErrUnexpectedEOF - } - mapvaluetemp = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - mapvalue = math.Float64frombits(mapvaluetemp) - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.MaximumResourceFraction[mapkey] = mapvalue + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -11451,7 +13757,7 @@ func (m *PriorityClassPoolResourceLimits) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueueList) Unmarshal(dAtA []byte) error { +func (m *RetryPolicyDeleteRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11474,17 +13780,17 @@ func (m *QueueList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueueList: wiretype end group for non-group") + return fmt.Errorf("proto: RetryPolicyDeleteRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueueList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RetryPolicyDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Queues", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSubmit @@ -11494,25 +13800,23 @@ func (m *QueueList) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSubmit } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSubmit } if postIndex > l { return io.ErrUnexpectedEOF } - m.Queues = append(m.Queues, &Queue{}) - if err := m.Queues[len(m.Queues)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -11535,7 +13839,7 @@ func (m *QueueList) Unmarshal(dAtA []byte) error { } return nil } -func (m *CancellationResult) Unmarshal(dAtA []byte) error { +func (m *RetryPolicyListRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11558,44 +13862,12 @@ func (m *CancellationResult) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CancellationResult: wiretype end group for non-group") + return fmt.Errorf("proto: RetryPolicyListRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CancellationResult: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RetryPolicyListRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CancelledIds", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubmit - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubmit - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CancelledIds = append(m.CancelledIds, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSubmit(dAtA[iNdEx:]) @@ -11617,7 +13889,7 @@ func (m *CancellationResult) Unmarshal(dAtA []byte) error { } return nil } -func (m *PreemptionResult) Unmarshal(dAtA []byte) error { +func (m *RetryPolicyList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -11640,15 +13912,15 @@ func (m *PreemptionResult) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PreemptionResult: wiretype end group for non-group") + return fmt.Errorf("proto: RetryPolicyList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PreemptionResult: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RetryPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreemptionResults", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RetryPolicies", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -11675,103 +13947,10 @@ func (m *PreemptionResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.PreemptionResults == nil { - m.PreemptionResults = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubmit - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLengthSubmit - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLengthSubmit - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skipSubmit(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubmit - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } + m.RetryPolicies = append(m.RetryPolicies, &RetryPolicy{}) + if err := m.RetryPolicies[len(m.RetryPolicies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.PreemptionResults[mapkey] = mapvalue iNdEx = postIndex default: iNdEx = preIndex diff --git a/pkg/api/submit.pb.gw.go b/pkg/api/submit.pb.gw.go index 59e891d3e3f..1a23b457971 100644 --- a/pkg/api/submit.pb.gw.go +++ b/pkg/api/submit.pb.gw.go @@ -511,6 +511,236 @@ func request_Submit_GetQueues_0(ctx context.Context, marshaler runtime.Marshaler } +func request_Submit_CreateRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client SubmitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicy + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateRetryPolicy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Submit_CreateRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server SubmitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicy + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateRetryPolicy(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Submit_UpdateRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client SubmitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicy + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.UpdateRetryPolicy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Submit_UpdateRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server SubmitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicy + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.UpdateRetryPolicy(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Submit_DeleteRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client SubmitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicyDeleteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.DeleteRetryPolicy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Submit_DeleteRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server SubmitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicyDeleteRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.DeleteRetryPolicy(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Submit_GetRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client SubmitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicyGetRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.GetRetryPolicy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Submit_GetRetryPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server SubmitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicyGetRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.GetRetryPolicy(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Submit_GetRetryPolicies_0(ctx context.Context, marshaler runtime.Marshaler, client SubmitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicyListRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetRetryPolicies(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Submit_GetRetryPolicies_0(ctx context.Context, marshaler runtime.Marshaler, server SubmitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RetryPolicyListRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetRetryPolicies(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterSubmitHandlerServer registers the http handlers for service Submit to "mux". // UnaryRPC :call SubmitServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -777,6 +1007,121 @@ func RegisterSubmitHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser return }) + mux.Handle("POST", pattern_Submit_CreateRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Submit_CreateRetryPolicy_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_CreateRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PUT", pattern_Submit_UpdateRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Submit_UpdateRetryPolicy_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_UpdateRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_Submit_DeleteRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Submit_DeleteRetryPolicy_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_DeleteRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Submit_GetRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Submit_GetRetryPolicy_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_GetRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Submit_GetRetryPolicies_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Submit_GetRetryPolicies_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_GetRetryPolicies_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1058,6 +1403,106 @@ func RegisterSubmitHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli }) + mux.Handle("POST", pattern_Submit_CreateRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Submit_CreateRetryPolicy_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_CreateRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PUT", pattern_Submit_UpdateRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Submit_UpdateRetryPolicy_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_UpdateRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_Submit_DeleteRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Submit_DeleteRetryPolicy_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_DeleteRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Submit_GetRetryPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Submit_GetRetryPolicy_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_GetRetryPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Submit_GetRetryPolicies_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Submit_GetRetryPolicies_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Submit_GetRetryPolicies_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1085,6 +1530,16 @@ var ( pattern_Submit_GetQueue_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "queue", "name"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Submit_GetQueues_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "batched", "queues"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Submit_CreateRetryPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "retry-policy"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Submit_UpdateRetryPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "retry-policy", "name"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Submit_DeleteRetryPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "retry-policy", "name"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Submit_GetRetryPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "retry-policy", "name"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Submit_GetRetryPolicies_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "retry-policies"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -1111,4 +1566,14 @@ var ( forward_Submit_GetQueue_0 = runtime.ForwardResponseMessage forward_Submit_GetQueues_0 = runtime.ForwardResponseStream + + forward_Submit_CreateRetryPolicy_0 = runtime.ForwardResponseMessage + + forward_Submit_UpdateRetryPolicy_0 = runtime.ForwardResponseMessage + + forward_Submit_DeleteRetryPolicy_0 = runtime.ForwardResponseMessage + + forward_Submit_GetRetryPolicy_0 = runtime.ForwardResponseMessage + + forward_Submit_GetRetryPolicies_0 = runtime.ForwardResponseMessage ) diff --git a/pkg/api/submit.proto b/pkg/api/submit.proto index 1b3eb1f4d1f..4cc7a95c884 100644 --- a/pkg/api/submit.proto +++ b/pkg/api/submit.proto @@ -202,6 +202,7 @@ message Queue { // A list of Kubernetes-like key-value labels, e.g. armadaproject.io/priority=critical repeated string labels_deprecated = 9 [deprecated=true]; map labels = 10; + string retry_policy = 11; } message PriorityClassResourceLimits { @@ -232,6 +233,60 @@ message PreemptionResult { map preemption_results = 1; } +// RetryPolicy defines rules that determine whether failed jobs should be retried. +// Operators create policies and assign them to queues by name. +message RetryPolicy { + string name = 1; + // retry_limit is the maximum number of retries after the initial failure. + // retry_limit: 3 allows up to 3 retries (4 total attempts before terminal + // failure). 0 means unlimited, subject to the scheduler's global cap. + uint32 retry_limit = 2; + RetryAction default_action = 3; + repeated RetryRule rules = 4; +} + +enum RetryAction { + RETRY_ACTION_UNSPECIFIED = 0; + RETRY_ACTION_FAIL = 1; + RETRY_ACTION_RETRY = 2; +} + +message RetryRule { + RetryAction action = 1; + repeated string on_conditions = 2; + RetryExitCodeMatcher on_exit_codes = 3; + string on_termination_message_pattern = 4; + // on_category matches against Error.failure_category. When set with on_subcategory, + // both must match. Mirrors the engine's Rule.OnCategory / Rule.OnSubcategory. + string on_category = 5; + string on_subcategory = 6; +} + +enum ExitCodeOperator { + EXIT_CODE_OPERATOR_UNSPECIFIED = 0; + EXIT_CODE_OPERATOR_IN = 1; + EXIT_CODE_OPERATOR_NOT_IN = 2; +} + +message RetryExitCodeMatcher { + ExitCodeOperator operator = 1; + repeated int32 values = 2; +} + +message RetryPolicyGetRequest { + string name = 1; +} + +message RetryPolicyDeleteRequest { + string name = 1; +} + +message RetryPolicyListRequest {} + +message RetryPolicyList { + repeated RetryPolicy retry_policies = 1; +} + //swagger:model message QueueGetRequest { string name = 1; @@ -321,6 +376,14 @@ service QueueService { rpc CancelOnQueue (QueueCancelRequest) returns (google.protobuf.Empty) {} } +service RetryPolicyService { + rpc CreateRetryPolicy(RetryPolicy) returns (google.protobuf.Empty); + rpc UpdateRetryPolicy(RetryPolicy) returns (google.protobuf.Empty); + rpc DeleteRetryPolicy(RetryPolicyDeleteRequest) returns (google.protobuf.Empty); + rpc GetRetryPolicy(RetryPolicyGetRequest) returns (RetryPolicy); + rpc GetRetryPolicies(RetryPolicyListRequest) returns (RetryPolicyList); +} + service Submit { rpc SubmitJobs (JobSubmitRequest) returns (JobSubmitResponse) { option (google.api.http) = { @@ -391,5 +454,32 @@ service Submit { get: "/v1/batched/queues" }; } + rpc CreateRetryPolicy(RetryPolicy) returns (google.protobuf.Empty) { + option (google.api.http) = { + post: "/v1/retry-policy" + body: "*" + }; + } + rpc UpdateRetryPolicy(RetryPolicy) returns (google.protobuf.Empty) { + option (google.api.http) = { + put: "/v1/retry-policy/{name}" + body: "*" + }; + } + rpc DeleteRetryPolicy(RetryPolicyDeleteRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/v1/retry-policy/{name}" + }; + } + rpc GetRetryPolicy(RetryPolicyGetRequest) returns (RetryPolicy) { + option (google.api.http) = { + get: "/v1/retry-policy/{name}" + }; + } + rpc GetRetryPolicies(RetryPolicyListRequest) returns (RetryPolicyList) { + option (google.api.http) = { + get: "/v1/retry-policies" + }; + } rpc Health(google.protobuf.Empty) returns (HealthCheckResponse); } diff --git a/pkg/client/queue/queue.go b/pkg/client/queue/queue.go index effb16b6422..af69a01892d 100644 --- a/pkg/client/queue/queue.go +++ b/pkg/client/queue/queue.go @@ -14,6 +14,7 @@ type Queue struct { ResourceLimitsByPriorityClassName map[string]api.PriorityClassResourceLimits Cordoned bool `json:"cordoned"` Labels map[string]string `json:"labels"` + RetryPolicy string `json:"retryPolicy"` } // NewQueue returns new Queue using the in parameter. Error is returned if @@ -62,6 +63,7 @@ func NewQueue(in *api.Queue) (Queue, error) { ResourceLimitsByPriorityClassName: resourceLimitsByPriorityClassName, Cordoned: in.Cordoned, Labels: in.Labels, + RetryPolicy: in.RetryPolicy, }, nil } @@ -75,8 +77,9 @@ func (q Queue) ToAPI() *api.Queue { func(p api.PriorityClassResourceLimits) *api.PriorityClassResourceLimits { return &p }), - Cordoned: q.Cordoned, - Labels: q.Labels, + Cordoned: q.Cordoned, + Labels: q.Labels, + RetryPolicy: q.RetryPolicy, } for _, permission := range q.Permissions { rv.Permissions = append(rv.Permissions, permission.ToAPI()) diff --git a/pkg/client/resource.go b/pkg/client/resource.go index 6d08f7a5900..1b37d2b5aa3 100644 --- a/pkg/client/resource.go +++ b/pkg/client/resource.go @@ -13,16 +13,18 @@ type Resource struct { type ResourceKind string const ( - ResourceKindQueue ResourceKind = "Queue" + ResourceKindQueue ResourceKind = "Queue" + ResourceKindRetryPolicy ResourceKind = "RetryPolicy" ) func NewResourceKind(in string) (ResourceKind, error) { - validValues := []ResourceKind{ResourceKindQueue} - if in != string(ResourceKindQueue) { + validValues := []ResourceKind{ResourceKindQueue, ResourceKindRetryPolicy} + switch in { + case string(ResourceKindQueue), string(ResourceKindRetryPolicy): + return ResourceKind(in), nil + default: return "", fmt.Errorf("invalid kind: %s. Valid values: %v", in, validValues) } - - return ResourceKind(in), nil } func (kind *ResourceKind) UnmarshalJSON(data []byte) error { diff --git a/pkg/client/retrypolicy/create.go b/pkg/client/retrypolicy/create.go new file mode 100644 index 00000000000..a97fd8ff95e --- /dev/null +++ b/pkg/client/retrypolicy/create.go @@ -0,0 +1,35 @@ +package retrypolicy + +import ( + "fmt" + + "github.com/armadaproject/armada/internal/common" + "github.com/armadaproject/armada/pkg/api" + "github.com/armadaproject/armada/pkg/client" +) + +type CreateAPI func(policy *api.RetryPolicy) error + +func Create(getConnectionDetails client.ConnectionDetails) CreateAPI { + return func(policy *api.RetryPolicy) error { + connectionDetails, err := getConnectionDetails() + if err != nil { + return fmt.Errorf("failed to obtain api connection details: %s", err) + } + conn, err := client.CreateApiConnection(connectionDetails) + if err != nil { + return fmt.Errorf("failed to connect to api because %s", err) + } + defer conn.Close() + + ctx, cancel := common.ContextWithDefaultTimeout() + defer cancel() + + c := api.NewRetryPolicyServiceClient(conn) + if _, err := c.CreateRetryPolicy(ctx, policy); err != nil { + return fmt.Errorf("create retry policy request failed: %s", err) + } + + return nil + } +} diff --git a/pkg/client/retrypolicy/delete.go b/pkg/client/retrypolicy/delete.go new file mode 100644 index 00000000000..9d1fbce7c33 --- /dev/null +++ b/pkg/client/retrypolicy/delete.go @@ -0,0 +1,35 @@ +package retrypolicy + +import ( + "fmt" + + "github.com/armadaproject/armada/internal/common" + "github.com/armadaproject/armada/pkg/api" + "github.com/armadaproject/armada/pkg/client" +) + +type DeleteAPI func(name string) error + +func Delete(getConnectionDetails client.ConnectionDetails) DeleteAPI { + return func(name string) error { + connectionDetails, err := getConnectionDetails() + if err != nil { + return fmt.Errorf("failed to obtain api connection details: %s", err) + } + conn, err := client.CreateApiConnection(connectionDetails) + if err != nil { + return fmt.Errorf("failed to connect to api because %s", err) + } + defer conn.Close() + + ctx, cancel := common.ContextWithDefaultTimeout() + defer cancel() + + c := api.NewRetryPolicyServiceClient(conn) + if _, err = c.DeleteRetryPolicy(ctx, &api.RetryPolicyDeleteRequest{Name: name}); err != nil { + return fmt.Errorf("delete retry policy request failed: %s", err) + } + + return nil + } +} diff --git a/pkg/client/retrypolicy/get.go b/pkg/client/retrypolicy/get.go new file mode 100644 index 00000000000..1e43b02d59e --- /dev/null +++ b/pkg/client/retrypolicy/get.go @@ -0,0 +1,63 @@ +package retrypolicy + +import ( + "fmt" + + "github.com/armadaproject/armada/internal/common" + "github.com/armadaproject/armada/pkg/api" + "github.com/armadaproject/armada/pkg/client" +) + +type GetAPI func(name string) (*api.RetryPolicy, error) + +func Get(getConnectionDetails client.ConnectionDetails) GetAPI { + return func(name string) (*api.RetryPolicy, error) { + connectionDetails, err := getConnectionDetails() + if err != nil { + return nil, fmt.Errorf("failed to obtain api connection details: %s", err) + } + conn, err := client.CreateApiConnection(connectionDetails) + if err != nil { + return nil, fmt.Errorf("failed to connect to api because %s", err) + } + defer conn.Close() + + ctx, cancel := common.ContextWithDefaultTimeout() + defer cancel() + + c := api.NewRetryPolicyServiceClient(conn) + policy, err := c.GetRetryPolicy(ctx, &api.RetryPolicyGetRequest{Name: name}) + if err != nil { + return nil, fmt.Errorf("get retry policy request failed: %s", err) + } + + return policy, nil + } +} + +type GetAllAPI func() ([]*api.RetryPolicy, error) + +func GetAll(getConnectionDetails client.ConnectionDetails) GetAllAPI { + return func() ([]*api.RetryPolicy, error) { + connectionDetails, err := getConnectionDetails() + if err != nil { + return nil, fmt.Errorf("failed to obtain api connection details: %s", err) + } + conn, err := client.CreateApiConnection(connectionDetails) + if err != nil { + return nil, fmt.Errorf("failed to connect to api because %s", err) + } + defer conn.Close() + + ctx, cancel := common.ContextWithDefaultTimeout() + defer cancel() + + c := api.NewRetryPolicyServiceClient(conn) + list, err := c.GetRetryPolicies(ctx, &api.RetryPolicyListRequest{}) + if err != nil { + return nil, fmt.Errorf("get retry policies request failed: %s", err) + } + + return list.RetryPolicies, nil + } +} diff --git a/pkg/client/retrypolicy/update.go b/pkg/client/retrypolicy/update.go new file mode 100644 index 00000000000..967b0ad053f --- /dev/null +++ b/pkg/client/retrypolicy/update.go @@ -0,0 +1,34 @@ +package retrypolicy + +import ( + "fmt" + + "github.com/armadaproject/armada/internal/common" + "github.com/armadaproject/armada/pkg/api" + "github.com/armadaproject/armada/pkg/client" +) + +type UpdateAPI func(policy *api.RetryPolicy) error + +func Update(getConnectionDetails client.ConnectionDetails) UpdateAPI { + return func(policy *api.RetryPolicy) error { + connectionDetails, err := getConnectionDetails() + if err != nil { + return fmt.Errorf("failed to obtain api connection details: %s", err) + } + conn, err := client.CreateApiConnection(connectionDetails) + if err != nil { + return fmt.Errorf("failed to connect to api because %s", err) + } + defer conn.Close() + + ctx, cancel := common.ContextWithDefaultTimeout() + defer cancel() + + c := api.NewRetryPolicyServiceClient(conn) + if _, err = c.UpdateRetryPolicy(ctx, policy); err != nil { + return fmt.Errorf("update retry policy request failed: %s", err) + } + return nil + } +} From b85c5a27e60d7e65378ac45e2885097b40ce3af5 Mon Sep 17 00:00:00 2001 From: Dejan Zele Pejchev Date: Fri, 8 May 2026 14:49:27 +0200 Subject: [PATCH 3/5] Plumb run index through scheduler API and pod naming Signed-off-by: Dejan Zele Pejchev --- internal/executor/domain/pod_metadata.go | 1 + internal/executor/util/kubernetes_object.go | 18 +- .../executor/util/kubernetes_objects_test.go | 55 +++ internal/scheduler/api.go | 34 +- internal/scheduler/api_test.go | 4 + internal/scheduler/database/job_repository.go | 5 +- .../migrations/037_add_job_run_index.sql | 1 + internal/scheduler/database/models.go | 1 + internal/scheduler/database/query.sql.go | 9 +- internal/scheduler/jobdb/job.go | 5 + internal/scheduler/jobdb/job_run.go | 15 + internal/scheduler/jobdb/job_run_test.go | 3 + internal/scheduler/jobdb/reconciliation.go | 1 + internal/scheduler/scheduler_test.go | 4 + internal/scheduler/schedulerapp.go | 1 + internal/scheduleringester/instructions.go | 1 + pkg/armadaevents/events.pb.go | 367 ++++++++++-------- pkg/armadaevents/events.proto | 5 + pkg/executorapi/executorapi.pb.go | 261 ++++++++----- pkg/executorapi/executorapi.proto | 7 + 20 files changed, 520 insertions(+), 278 deletions(-) create mode 100644 internal/scheduler/database/migrations/037_add_job_run_index.sql diff --git a/internal/executor/domain/pod_metadata.go b/internal/executor/domain/pod_metadata.go index f08c7649868..f2a9932f670 100644 --- a/internal/executor/domain/pod_metadata.go +++ b/internal/executor/domain/pod_metadata.go @@ -3,6 +3,7 @@ package domain const ( JobId = "armada_job_id" JobRunId = "armada_job_run_id" + JobRunIndex = "armada_job_run_index" PodNumber = "armada_pod_number" PodCount = "armada_pod_count" JobSetId = "armada_jobset_id" diff --git a/internal/executor/util/kubernetes_object.go b/internal/executor/util/kubernetes_object.go index 658e086226b..abdf47e6c5d 100644 --- a/internal/executor/util/kubernetes_object.go +++ b/internal/executor/util/kubernetes_object.go @@ -120,13 +120,25 @@ func CreatePodFromExecutorApiJob(job *executorapi.JobRunLease, defaults *configu return nil, fmt.Errorf("job %s is invalid, runId is empty", jobId) } - labels := util.MergeMaps(job.Job.ObjectMeta.Labels, map[string]string{ + // When the scheduler populates JobRunIndex (retry policy is enabled), we + // disambiguate retry attempts by suffixing the pod name and adding an + // armada_job_run_index label. With the field unset (legacy / FF off), we + // preserve the pre-existing pod-name format byte-for-byte so that no + // downstream tooling that parses pod names breaks. + labels := map[string]string{ domain.JobId: jobId, domain.JobRunId: runId, domain.Queue: job.Queue, domain.PodNumber: strconv.Itoa(0), domain.PodCount: strconv.Itoa(1), - }) + } + podName := common.PodNamePrefix + job.Job.JobId + "-" + strconv.Itoa(0) + if job.JobRunIndex != nil { + runIndex := strconv.FormatUint(uint64(job.JobRunIndex.GetValue()), 10) + labels[domain.JobRunIndex] = runIndex + podName = podName + "-" + runIndex + } + labels = util.MergeMaps(job.Job.ObjectMeta.Labels, labels) annotation := util.MergeMaps(job.Job.ObjectMeta.Annotations, map[string]string{ domain.JobSetId: job.Jobset, domain.Owner: job.User, @@ -139,7 +151,7 @@ func CreatePodFromExecutorApiJob(job *executorapi.JobRunLease, defaults *configu pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: common.PodNamePrefix + job.Job.JobId + "-" + strconv.Itoa(0), + Name: podName, Labels: labels, Annotations: annotation, Namespace: job.Job.ObjectMeta.Namespace, diff --git a/internal/executor/util/kubernetes_objects_test.go b/internal/executor/util/kubernetes_objects_test.go index 8e7d23ab269..313fd9dc082 100644 --- a/internal/executor/util/kubernetes_objects_test.go +++ b/internal/executor/util/kubernetes_objects_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/gogo/protobuf/types" "github.com/google/uuid" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" @@ -135,6 +136,60 @@ func TestCreatePodFromExecutorApiJob(t *testing.T) { assert.Equal(t, expectedPod, result) } +// TestCreatePodFromExecutorApiJob_WithRunIndex covers the new pod-name format +// used when the scheduler populates the optional JobRunIndex field. The format +// becomes armada--0- and an armada_job_run_index label is +// added so downstream tooling can distinguish retry attempts. +func TestCreatePodFromExecutorApiJob_WithRunIndex(t *testing.T) { + runId := uuid.NewString() + jobId := util.NewULID() + + validJobLease := &executorapi.JobRunLease{ + JobRunId: runId, + JobRunIndex: &types.UInt32Value{Value: 2}, + Queue: "queue", + Jobset: "job-set", + User: "user", + Job: &armadaevents.SubmitJob{ + ObjectMeta: &armadaevents.ObjectMeta{ + Labels: map[string]string{}, + Annotations: map[string]string{}, + Namespace: "test-namespace", + }, + JobId: jobId, + MainObject: &armadaevents.KubernetesMainObject{ + Object: &armadaevents.KubernetesMainObject_PodSpec{ + PodSpec: &armadaevents.PodSpecWithAvoidList{ + PodSpec: &v1.PodSpec{ + Containers: []v1.Container{{Name: "test", Image: "test"}}, + }, + }, + }, + }, + }, + } + + result, err := CreatePodFromExecutorApiJob(validJobLease, &configuration.PodDefaults{SchedulerName: "scheduler-name"}) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("armada-%s-0-2", jobId), result.Name) + assert.Equal(t, "2", result.Labels[domain.JobRunIndex]) +} + +// TestCreatePodFromExecutorApiJob_NoRunIndex confirms the pre-retry pod-name +// format is preserved exactly when the scheduler leaves JobRunIndex unset +// (which is the case for the legacy scheduler, the feature flag off, or an +// older scheduler talking to a newer executor). +func TestCreatePodFromExecutorApiJob_NoRunIndex(t *testing.T) { + lease := createBasicJobRunLease() + jobId := lease.Job.JobId + + result, err := CreatePodFromExecutorApiJob(lease, &configuration.PodDefaults{}) + assert.NoError(t, err) + assert.Equal(t, fmt.Sprintf("armada-%s-0", jobId), result.Name) + _, hasRunIndexLabel := result.Labels[domain.JobRunIndex] + assert.False(t, hasRunIndexLabel, "armada_job_run_index label must not be set when JobRunIndex is nil") +} + func TestCreatePodFromExecutorApiJob_Invalid(t *testing.T) { lease := createBasicJobRunLease() _, err := CreatePodFromExecutorApiJob(lease, &configuration.PodDefaults{}) diff --git a/internal/scheduler/api.go b/internal/scheduler/api.go index 55b3f0c9741..4908b709ece 100644 --- a/internal/scheduler/api.go +++ b/internal/scheduler/api.go @@ -22,6 +22,7 @@ import ( protoutil "github.com/armadaproject/armada/internal/common/proto" "github.com/armadaproject/armada/internal/common/pulsarutils" priorityTypes "github.com/armadaproject/armada/internal/common/types" + "github.com/armadaproject/armada/internal/scheduler/configuration" "github.com/armadaproject/armada/internal/scheduler/database" "github.com/armadaproject/armada/internal/scheduler/schedulerobjects" "github.com/armadaproject/armada/internal/server/permissions" @@ -49,8 +50,12 @@ type ExecutorApi struct { nodeIdLabel string // See scheduling schedulingConfig. priorityClassNameOverride *string - clock clock.Clock - authorizer auth.ActionAuthorizer + // Retry policy config; when Enabled is true, the executor api populates the + // optional JobRunIndex field on outgoing JobRunLease messages so the + // executor can disambiguate retry attempts by pod name. + retryPolicy configuration.RetryPolicyConfig + clock clock.Clock + authorizer auth.ActionAuthorizer } func NewExecutorApi(publisher pulsarutils.Publisher[*armadaevents.EventSequence], @@ -61,6 +66,7 @@ func NewExecutorApi(publisher pulsarutils.Publisher[*armadaevents.EventSequence] nodeIdLabel string, priorityClassNameOverride *string, priorityClasses map[string]priorityTypes.PriorityClass, + retryPolicy configuration.RetryPolicyConfig, authorizer auth.ActionAuthorizer, ) (*ExecutorApi, error) { if len(allowedPriorities) == 0 { @@ -75,6 +81,7 @@ func NewExecutorApi(publisher pulsarutils.Publisher[*armadaevents.EventSequence] nodeIdLabel: nodeIdLabel, priorityClassNameOverride: priorityClassNameOverride, priorityClasses: priorityClasses, + retryPolicy: retryPolicy, clock: clock.RealClock{}, authorizer: authorizer, }, nil @@ -169,16 +176,23 @@ func (srv *ExecutorApi) LeaseJobRuns(stream executorapi.ExecutorApi_LeaseJobRuns } } + jobRunLease := &executorapi.JobRunLease{ + JobRunId: lease.RunID, + Queue: lease.Queue, + Jobset: lease.JobSet, + User: lease.UserID, + Groups: groups, + Job: submitMsg, + } + // Only populate JobRunIndex when the retry policy engine is enabled, + // otherwise the executor falls back to the legacy pod-name format. The + // optional field uses explicit presence so a value of 0 is meaningful. + if srv.retryPolicy.Enabled { + jobRunLease.JobRunIndex = &types.UInt32Value{Value: lease.RunIndex} + } err := stream.Send(&executorapi.LeaseStreamMessage{ Event: &executorapi.LeaseStreamMessage_Lease{ - Lease: &executorapi.JobRunLease{ - JobRunId: lease.RunID, - Queue: lease.Queue, - Jobset: lease.JobSet, - User: lease.UserID, - Groups: groups, - Job: submitMsg, - }, + Lease: jobRunLease, }, }) if err != nil { diff --git a/internal/scheduler/api_test.go b/internal/scheduler/api_test.go index 72846d9f734..6b38e796a0a 100644 --- a/internal/scheduler/api_test.go +++ b/internal/scheduler/api_test.go @@ -341,6 +341,7 @@ func TestExecutorApi_LeaseJobRuns(t *testing.T) { "kubernetes.io/hostname", nil, priorityClasses, + schedulerconfig.RetryPolicyConfig{}, mockAuthorizer, ) require.NoError(t, err) @@ -398,6 +399,7 @@ func TestExecutorApi_LeaseJobRuns_Unauthorised(t *testing.T) { "kubernetes.io/hostname", nil, priorityClasses, + schedulerconfig.RetryPolicyConfig{}, mockAuthorizer, ) @@ -527,6 +529,7 @@ func TestExecutorApi_Publish(t *testing.T) { "kubernetes.io/hostname", nil, priorityClasses, + schedulerconfig.RetryPolicyConfig{}, mockAuthorizer, ) @@ -574,6 +577,7 @@ func TestExecutorApi_Publish_Unauthorised(t *testing.T) { "kubernetes.io/hostname", nil, priorityClasses, + schedulerconfig.RetryPolicyConfig{}, mockAuthorizer, ) diff --git a/internal/scheduler/database/job_repository.go b/internal/scheduler/database/job_repository.go index 96da6989576..78a4a6bc404 100644 --- a/internal/scheduler/database/job_repository.go +++ b/internal/scheduler/database/job_repository.go @@ -24,6 +24,7 @@ type hasSerial interface { type JobRunLease struct { RunID string + RunIndex uint32 Queue string Pool string JobSet string @@ -355,7 +356,7 @@ func (r *PostgresJobRepository) FetchJobRunLeases(ctx *armadacontext.Context, ex } query := ` - SELECT jr.run_id, jr.node, j.queue, j.job_set, jr.pool, j.user_id, j.groups, j.submit_message, jr.pod_requirements_overlay + SELECT jr.run_id, jr.run_index, jr.node, j.queue, j.job_set, jr.pool, j.user_id, j.groups, j.submit_message, jr.pod_requirements_overlay FROM runs jr LEFT JOIN %s as tmp ON (tmp.run_id = jr.run_id) JOIN jobs j @@ -374,7 +375,7 @@ func (r *PostgresJobRepository) FetchJobRunLeases(ctx *armadacontext.Context, ex defer rows.Close() for rows.Next() { run := JobRunLease{} - err = rows.Scan(&run.RunID, &run.Node, &run.Queue, &run.JobSet, &run.Pool, &run.UserID, &run.Groups, &run.SubmitMessage, &run.PodRequirementsOverlay) + err = rows.Scan(&run.RunID, &run.RunIndex, &run.Node, &run.Queue, &run.JobSet, &run.Pool, &run.UserID, &run.Groups, &run.SubmitMessage, &run.PodRequirementsOverlay) if err != nil { return errors.WithStack(err) } diff --git a/internal/scheduler/database/migrations/037_add_job_run_index.sql b/internal/scheduler/database/migrations/037_add_job_run_index.sql new file mode 100644 index 00000000000..f1186970ef3 --- /dev/null +++ b/internal/scheduler/database/migrations/037_add_job_run_index.sql @@ -0,0 +1 @@ +ALTER TABLE runs ADD COLUMN IF NOT EXISTS run_index bigint NOT NULL DEFAULT 0; diff --git a/internal/scheduler/database/models.go b/internal/scheduler/database/models.go index 42828345adc..d07a473b89e 100644 --- a/internal/scheduler/database/models.go +++ b/internal/scheduler/database/models.go @@ -93,4 +93,5 @@ type Run struct { Pool string `db:"pool"` Terminated bool `db:"terminated"` PreemptReason *string `db:"preempt_reason"` + RunIndex int64 `db:"run_index"` } diff --git a/internal/scheduler/database/query.sql.go b/internal/scheduler/database/query.sql.go index 6a86980cf98..65f961b05eb 100644 --- a/internal/scheduler/database/query.sql.go +++ b/internal/scheduler/database/query.sql.go @@ -481,7 +481,7 @@ func (q *Queries) SelectInitialJobs(ctx context.Context, arg SelectInitialJobsPa } const selectInitialRuns = `-- name: SelectInitialRuns :many -SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue, pool, terminated, preempt_reason FROM runs WHERE serial > $1 AND job_id = ANY($3::text[]) ORDER BY serial LIMIT $2 +SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue, pool, terminated, preempt_reason, run_index FROM runs WHERE serial > $1 AND job_id = ANY($3::text[]) ORDER BY serial LIMIT $2 ` type SelectInitialRunsParams struct { @@ -528,6 +528,7 @@ func (q *Queries) SelectInitialRuns(ctx context.Context, arg SelectInitialRunsPa &i.Pool, &i.Terminated, &i.PreemptReason, + &i.RunIndex, ); err != nil { return nil, err } @@ -882,7 +883,7 @@ func (q *Queries) SelectNewJobs(ctx context.Context, arg SelectNewJobsParams) ([ } const selectNewRuns = `-- name: SelectNewRuns :many -SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue, pool, terminated, preempt_reason FROM runs WHERE serial > $1 ORDER BY serial LIMIT $2 +SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue, pool, terminated, preempt_reason, run_index FROM runs WHERE serial > $1 ORDER BY serial LIMIT $2 ` type SelectNewRunsParams struct { @@ -928,6 +929,7 @@ func (q *Queries) SelectNewRuns(ctx context.Context, arg SelectNewRunsParams) ([ &i.Pool, &i.Terminated, &i.PreemptReason, + &i.RunIndex, ); err != nil { return nil, err } @@ -940,7 +942,7 @@ func (q *Queries) SelectNewRuns(ctx context.Context, arg SelectNewRunsParams) ([ } const selectNewRunsForJobs = `-- name: SelectNewRunsForJobs :many -SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue, pool, terminated, preempt_reason FROM runs WHERE serial > $1 AND job_id = ANY($2::text[]) ORDER BY serial +SELECT run_id, job_id, created, job_set, executor, node, cancelled, running, succeeded, failed, returned, run_attempted, serial, last_modified, leased_timestamp, pending_timestamp, running_timestamp, terminated_timestamp, scheduled_at_priority, preempted, pending, preempted_timestamp, pod_requirements_overlay, preempt_requested, queue, pool, terminated, preempt_reason, run_index FROM runs WHERE serial > $1 AND job_id = ANY($2::text[]) ORDER BY serial ` type SelectNewRunsForJobsParams struct { @@ -986,6 +988,7 @@ func (q *Queries) SelectNewRunsForJobs(ctx context.Context, arg SelectNewRunsFor &i.Pool, &i.Terminated, &i.PreemptReason, + &i.RunIndex, ); err != nil { return nil, err } diff --git a/internal/scheduler/jobdb/job.go b/internal/scheduler/jobdb/job.go index 9145b433613..f103ec3c93f 100644 --- a/internal/scheduler/jobdb/job.go +++ b/internal/scheduler/jobdb/job.go @@ -769,10 +769,15 @@ func (job *Job) ValidateResourceRequests() error { } // WithNewRun creates a copy of the job with a new run on the given executor. +// The new run's index is derived from the current number of runs on the job +// (zero-based), so each retry attempt gets a unique, monotonically increasing +// index. func (job *Job) WithNewRun(executor, nodeId, nodeName, pool string, scheduledAtPriority int32) *Job { now := job.jobDb.clock.Now() + nextRunIndex := uint32(len(job.runsById)) return job.WithUpdatedRun(job.jobDb.CreateRun( job.jobDb.uuidProvider.New(), + nextRunIndex, job.Id(), now.UnixNano(), executor, diff --git a/internal/scheduler/jobdb/job_run.go b/internal/scheduler/jobdb/job_run.go index c015b796e39..dd57ee6641d 100644 --- a/internal/scheduler/jobdb/job_run.go +++ b/internal/scheduler/jobdb/job_run.go @@ -15,6 +15,11 @@ import ( type JobRun struct { // Unique identifier for the run. id string + // Zero-based attempt counter for this run within its job. The first run is + // always 0; incremented when the scheduler retries a failed run under a + // retry policy. Used by the executor to disambiguate pod names across + // attempts. + index uint32 // Id of the job this run is associated with. jobId string // Time at which the run was created. @@ -159,6 +164,9 @@ func (run *JobRun) Equal(other *JobRun) bool { if run.id != other.id { return false } + if run.index != other.index { + return false + } if run.jobId != other.jobId { return false } @@ -215,6 +223,7 @@ func MinimalRun(id string, creationTime int64) *JobRun { // CreateRun creates a new scheduler job run from a database job run func (jobDb *JobDb) CreateRun( id string, + index uint32, jobId string, creationTime int64, executor string, @@ -241,6 +250,7 @@ func (jobDb *JobDb) CreateRun( ) *JobRun { return &JobRun{ id: id, + index: index, jobId: jobId, created: creationTime, executor: jobDb.stringInterner.Intern(executor), @@ -272,6 +282,11 @@ func (run *JobRun) Id() string { return run.id } +// Index returns the zero-based attempt counter for this run within its job. +func (run *JobRun) Index() uint32 { + return run.index +} + // JobId returns the id of the job this run is associated with. func (run *JobRun) JobId() string { return run.jobId diff --git a/internal/scheduler/jobdb/job_run_test.go b/internal/scheduler/jobdb/job_run_test.go index 3307341e968..9c51390c2af 100644 --- a/internal/scheduler/jobdb/job_run_test.go +++ b/internal/scheduler/jobdb/job_run_test.go @@ -49,6 +49,7 @@ func init() { var baseJobRun = jobDb.CreateRun( uuid.New().String(), + 0, uuid.NewString(), 5, "test-executor", @@ -127,6 +128,7 @@ func TestJobRun_TestRunAttempted(t *testing.T) { func TestDeepCopy(t *testing.T) { run := jobDb.CreateRun( uuid.NewString(), + 0, "job id", 1, "executor", @@ -153,6 +155,7 @@ func TestDeepCopy(t *testing.T) { ) expected := jobDb.CreateRun( run.id, + run.index, "job id", 1, "executor", diff --git a/internal/scheduler/jobdb/reconciliation.go b/internal/scheduler/jobdb/reconciliation.go index 4ed69510a02..fc6fcf828c6 100644 --- a/internal/scheduler/jobdb/reconciliation.go +++ b/internal/scheduler/jobdb/reconciliation.go @@ -359,6 +359,7 @@ func (jobDb *JobDb) schedulerRunFromDatabaseRun(dbRun *database.Run) *JobRun { nodeId := api.NodeIdFromExecutorAndNodeName(dbRun.Executor, dbRun.Node) return jobDb.CreateRun( dbRun.RunID, + uint32(dbRun.RunIndex), dbRun.JobID, dbRun.Created, dbRun.Executor, diff --git a/internal/scheduler/scheduler_test.go b/internal/scheduler/scheduler_test.go index e428afe5de7..d20da0966f1 100644 --- a/internal/scheduler/scheduler_test.go +++ b/internal/scheduler/scheduler_test.go @@ -247,6 +247,7 @@ var returnedOnceLeasedJob = testfixtures.NewJob( true, ).WithUpdatedRun(testfixtures.JobDb.CreateRun( uuid.NewString(), + 0, "01h3w2wtdchtc80hgyp782shrv", 0, "testExecutor", @@ -333,6 +334,7 @@ var ( true, ).WithUpdatedRun(testfixtures.JobDb.CreateRun( uuid.NewString(), + 0, requeuedJobId, time.Now().Unix(), "testExecutor", @@ -1551,6 +1553,7 @@ func TestScheduler_TestSyncInitialState(t *testing.T) { queuedJob.WithUpdatedRun( testfixtures.JobDb.CreateRun( leasedJob.LatestRun().Id(), + 0, queuedJob.Id(), 123, "test-executor", @@ -1713,6 +1716,7 @@ func TestScheduler_TestSyncState(t *testing.T) { queuedJob.WithUpdatedRun( testfixtures.JobDb.CreateRun( leasedJob.LatestRun().Id(), + 0, queuedJob.Id(), 123, "test-executor", diff --git a/internal/scheduler/schedulerapp.go b/internal/scheduler/schedulerapp.go index 8ec24a06f62..f2da6784f1f 100644 --- a/internal/scheduler/schedulerapp.go +++ b/internal/scheduler/schedulerapp.go @@ -291,6 +291,7 @@ func Run(config schedulerconfig.Configuration) error { config.Scheduling.NodeIdLabel, config.Scheduling.PriorityClassNameOverride, config.Scheduling.PriorityClasses, + config.Scheduling.RetryPolicy, authorizer, ) if err != nil { diff --git a/internal/scheduleringester/instructions.go b/internal/scheduleringester/instructions.go index 57f249c53b9..4ec347139ad 100644 --- a/internal/scheduleringester/instructions.go +++ b/internal/scheduleringester/instructions.go @@ -219,6 +219,7 @@ func (c *JobSetEventsInstructionConverter) handleJobRunLeased(jobRunLeased *arma ScheduledAtPriority: scheduledAtPriority, LeasedTimestamp: &eventTime, PodRequirementsOverlay: PodRequirementsOverlay, + RunIndex: int64(jobRunLeased.GetRunIndex()), }, }}, UpdateJobQueuedState{jobRunLeased.JobId: &JobQueuedStateUpdate{ diff --git a/pkg/armadaevents/events.pb.go b/pkg/armadaevents/events.pb.go index ed7f800a3b7..40f4d2bbc92 100644 --- a/pkg/armadaevents/events.pb.go +++ b/pkg/armadaevents/events.pb.go @@ -1654,6 +1654,11 @@ type JobRunLeased struct { // pool is the pool this run was scheduled on to // This would be determined by the pool of the node this run was scheduled on to, at the time of scheduling Pool string `protobuf:"bytes,12,opt,name=pool,proto3" json:"pool,omitempty"` + // run_index is the zero-based attempt counter for this run within the job. + // Always 0 for the first attempt. Incremented by the scheduler when retrying + // a failed run under a retry policy. Carried in the event so the + // scheduler-ingester can persist it on the runs row. + RunIndex uint32 `protobuf:"varint,13,opt,name=run_index,json=runIndex,proto3" json:"runIndex,omitempty"` } func (m *JobRunLeased) Reset() { *m = JobRunLeased{} } @@ -1752,6 +1757,13 @@ func (m *JobRunLeased) GetPool() string { return "" } +func (m *JobRunLeased) GetRunIndex() uint32 { + if m != nil { + return m.RunIndex + } + return 0 +} + // Indicates that a job has been assigned to nodes by Kubernetes. type JobRunAssigned struct { // Runtime information, e.g., which node the job is running on, its IP address etc, @@ -3751,13 +3763,13 @@ func init() { func init() { proto.RegisterFile("pkg/armadaevents/events.proto", fileDescriptor_6aab92ca59e015f8) } var fileDescriptor_6aab92ca59e015f8 = []byte{ - // 3787 bytes of a gzipped FileDescriptorProto + // 3809 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3b, 0x4d, 0x6f, 0x1b, 0xd7, 0xb5, 0x1e, 0x7e, 0xf3, 0x50, 0xa2, 0xe8, 0xab, 0x0f, 0xd3, 0x4a, 0x2c, 0xca, 0x74, 0x5e, 0x62, 0x07, 0x09, 0xe5, 0x38, 0x2f, 0x0f, 0xf9, 0x78, 0x48, 0x20, 0xda, 0xf2, 0x87, 0x62, 0xd9, 0x32, 0x65, 0xe5, 0xf9, 0x3d, 0x04, 0x60, 0x86, 0x9c, 0x2b, 0x6a, 0x2c, 0x72, 0x86, 0x99, 0x0f, 0x45, - 0x02, 0x02, 0xbc, 0xa4, 0x48, 0xbb, 0xce, 0xa6, 0x40, 0x91, 0x4d, 0xb3, 0xe9, 0xa2, 0x05, 0xba, - 0x6c, 0x7f, 0x43, 0x17, 0x45, 0x91, 0x4d, 0x81, 0x6e, 0x4a, 0x14, 0x09, 0xba, 0xe1, 0xa2, 0x3f, + 0x02, 0x02, 0xbc, 0xa4, 0x48, 0xbb, 0xce, 0xa6, 0x40, 0x91, 0x4d, 0xbb, 0xe9, 0xa2, 0x05, 0xba, + 0x6c, 0x7f, 0x43, 0x17, 0x45, 0x91, 0x4d, 0x80, 0x6e, 0x4a, 0x14, 0x09, 0xba, 0xe1, 0xa2, 0x3f, 0x20, 0xab, 0xe2, 0x7e, 0xcc, 0xcc, 0xbd, 0xc3, 0x4b, 0x8b, 0x72, 0x2c, 0xc3, 0x41, 0x56, 0xd2, 0x9c, 0xcf, 0x3b, 0xe7, 0x9c, 0x7b, 0xe6, 0x9c, 0x73, 0x2f, 0xe1, 0x5c, 0x7f, 0xaf, 0xb3, 0xa2, 0x3b, 0x3d, 0xdd, 0xd0, 0xf1, 0x3e, 0xb6, 0x3c, 0x77, 0x85, 0xfd, 0xa9, 0xf5, 0x1d, 0xdb, 0xb3, @@ -3777,7 +3789,7 @@ var fileDescriptor_6aab92ca59e015f8 = []byte{ 0x4a, 0x89, 0x80, 0x6e, 0x19, 0x02, 0x4b, 0x86, 0x41, 0xd0, 0x2b, 0x90, 0xe9, 0x38, 0xb6, 0xdf, 0x77, 0xcb, 0xa9, 0xe5, 0x64, 0x40, 0xcd, 0x20, 0x22, 0x35, 0x83, 0xa0, 0xbb, 0x90, 0x61, 0x0e, 0x2c, 0xa7, 0x97, 0x93, 0x17, 0x0b, 0x57, 0xce, 0xd7, 0x44, 0xaf, 0xd6, 0xa4, 0x17, 0x66, 0x4f, - 0x4c, 0x20, 0xc3, 0x8b, 0x02, 0x79, 0x1c, 0xfc, 0x71, 0x16, 0xd2, 0x94, 0x0e, 0xbd, 0x0f, 0xd9, + 0x4c, 0x20, 0xc3, 0x8b, 0x02, 0x79, 0x1c, 0xfc, 0x69, 0x16, 0xd2, 0x94, 0x0e, 0xbd, 0x0f, 0xd9, 0xb6, 0x83, 0x89, 0xf5, 0xcb, 0x68, 0x59, 0xbb, 0x58, 0xb8, 0xb2, 0x58, 0x63, 0x5e, 0xad, 0x05, 0x5e, 0xad, 0xdd, 0x0f, 0xbc, 0x5a, 0x9f, 0x1f, 0x0e, 0x2a, 0xa7, 0x39, 0xb9, 0x20, 0x35, 0x90, 0x80, 0x36, 0x21, 0xef, 0xfa, 0xad, 0x9e, 0xe9, 0xad, 0xdb, 0x2d, 0x6a, 0xef, 0xc2, 0x95, 0x33, @@ -3830,165 +3842,167 @@ var fileDescriptor_6aab92ca59e015f8 = []byte{ 0x6c, 0x4e, 0x85, 0x47, 0x2f, 0x43, 0x86, 0xb4, 0x15, 0xa6, 0x41, 0xab, 0x23, 0xde, 0x82, 0x3c, 0xb4, 0x5b, 0x52, 0x63, 0x90, 0xa6, 0x00, 0x42, 0xeb, 0xf8, 0x16, 0xa1, 0xcd, 0x46, 0xb4, 0x8e, 0x6f, 0xc9, 0xb4, 0x14, 0x40, 0x9d, 0xa1, 0xef, 0x77, 0xd4, 0xce, 0xc8, 0x4d, 0xea, 0x8c, 0xd5, - 0xfd, 0xce, 0x23, 0x9d, 0xa1, 0xab, 0xf0, 0xa2, 0x33, 0x94, 0x04, 0x8b, 0x5f, 0x6b, 0xb0, 0x38, - 0xde, 0xcf, 0xe8, 0x02, 0x24, 0xf7, 0xf0, 0x21, 0xef, 0xc9, 0x4e, 0x0f, 0x07, 0x95, 0xe9, 0x3d, - 0x7c, 0x28, 0x48, 0x25, 0x58, 0xf4, 0xbf, 0x90, 0xde, 0xd7, 0xbb, 0x3e, 0xe6, 0x25, 0x7f, 0xad, - 0xc6, 0xda, 0xc9, 0x9a, 0xd8, 0x4e, 0xd6, 0xfa, 0x7b, 0x1d, 0x02, 0xa8, 0x05, 0x56, 0xa8, 0xdd, - 0xf3, 0x75, 0xcb, 0x33, 0xbd, 0x43, 0x66, 0x3b, 0x2a, 0x40, 0xb4, 0x1d, 0x05, 0xbc, 0x9d, 0x78, - 0x53, 0x5b, 0xfc, 0xb5, 0x06, 0x67, 0xc7, 0xfa, 0xfb, 0x99, 0x58, 0x21, 0x31, 0xe2, 0x78, 0xff, - 0x3c, 0x0b, 0x4b, 0x5c, 0x4f, 0xe5, 0xb4, 0x52, 0x62, 0x3d, 0x95, 0x4b, 0x94, 0x92, 0xd5, 0xef, - 0x33, 0x90, 0x0f, 0x1b, 0x3c, 0x74, 0x13, 0x4a, 0x06, 0x36, 0xfc, 0x7e, 0xd7, 0x6c, 0xd3, 0x48, - 0x23, 0x41, 0xcd, 0x3a, 0x6a, 0x9a, 0x5d, 0x25, 0x9c, 0x14, 0xde, 0x33, 0x31, 0x14, 0xba, 0x02, - 0x39, 0xde, 0xc8, 0x1c, 0xd2, 0xbc, 0x36, 0x5d, 0x5f, 0x18, 0x0e, 0x2a, 0x28, 0x80, 0x09, 0xac, - 0x21, 0x1d, 0x6a, 0x00, 0xb0, 0xc9, 0xc0, 0x06, 0xf6, 0x74, 0xde, 0x52, 0x95, 0xe5, 0xdd, 0x70, - 0x37, 0xc4, 0xb3, 0x1e, 0x3f, 0xa2, 0x17, 0x7b, 0xfc, 0x08, 0x8a, 0x3e, 0x04, 0xe8, 0xe9, 0xa6, - 0xc5, 0xf8, 0x78, 0xff, 0x54, 0x1d, 0x97, 0x61, 0x37, 0x42, 0x4a, 0x26, 0x3d, 0xe2, 0x14, 0xa5, - 0x47, 0x50, 0x74, 0x17, 0xb2, 0x7c, 0x96, 0x51, 0xce, 0xd0, 0xcd, 0xbb, 0x34, 0x4e, 0x34, 0x17, - 0x4b, 0xbb, 0x71, 0xce, 0x22, 0x76, 0xe3, 0x1c, 0x44, 0xcc, 0xd6, 0x35, 0x77, 0xb0, 0x67, 0xf6, - 0x30, 0xcd, 0x26, 0xdc, 0x6c, 0x01, 0x4c, 0x34, 0x5b, 0x00, 0x43, 0x6f, 0x02, 0xe8, 0xde, 0x86, - 0xed, 0x7a, 0x77, 0xad, 0x36, 0xa6, 0x1d, 0x51, 0x8e, 0x2d, 0x3f, 0x82, 0x8a, 0xcb, 0x8f, 0xa0, - 0xe8, 0x1d, 0x28, 0xf4, 0xf9, 0x17, 0xb8, 0xd5, 0xc5, 0xb4, 0xe3, 0xc9, 0xb1, 0x82, 0x41, 0x00, - 0x0b, 0xbc, 0x22, 0x35, 0xba, 0x01, 0x33, 0x6d, 0xdb, 0x6a, 0xfb, 0x8e, 0x83, 0xad, 0xf6, 0xe1, - 0x96, 0xbe, 0x83, 0x69, 0x77, 0x93, 0x63, 0xa1, 0x12, 0x43, 0x89, 0xa1, 0x12, 0x43, 0xa1, 0x37, - 0x20, 0x1f, 0x4e, 0x86, 0x68, 0x03, 0x93, 0xe7, 0x83, 0x86, 0x00, 0x28, 0x30, 0x47, 0x94, 0x64, - 0xf1, 0xa6, 0x7b, 0x8d, 0x07, 0x1d, 0xa6, 0x4d, 0x09, 0x5f, 0xbc, 0x00, 0x16, 0x17, 0x2f, 0x80, - 0x85, 0xfc, 0x5e, 0x3c, 0x32, 0xbf, 0x5f, 0x87, 0x12, 0x3e, 0x60, 0xd3, 0xad, 0x26, 0x61, 0xf2, - 0x1d, 0x93, 0xd6, 0xf3, 0x79, 0xd6, 0x49, 0x05, 0xb8, 0x75, 0xbb, 0xb5, 0xed, 0x98, 0x02, 0x7b, - 0x51, 0xc6, 0x84, 0xdb, 0x6e, 0xba, 0x54, 0x5c, 0x4f, 0xe5, 0x66, 0x4a, 0xa5, 0xea, 0x9f, 0x35, - 0x98, 0x53, 0x45, 0x5f, 0x6c, 0x27, 0x68, 0x4f, 0x64, 0x27, 0x7c, 0x00, 0xb9, 0xbe, 0x6d, 0x34, - 0xdd, 0x3e, 0x6e, 0xf3, 0xbc, 0x12, 0xdb, 0x07, 0x9b, 0xb6, 0xb1, 0xd5, 0xc7, 0xed, 0xff, 0x31, - 0xbd, 0xdd, 0xd5, 0x7d, 0xdb, 0x34, 0x6e, 0x9b, 0x2e, 0x0f, 0xd8, 0x3e, 0xc3, 0x48, 0xc5, 0x4e, - 0x96, 0x03, 0xeb, 0x39, 0xc8, 0x30, 0x2d, 0xd5, 0xbf, 0x24, 0xa1, 0x14, 0x8f, 0xf8, 0x1f, 0xd3, - 0xab, 0xa0, 0x07, 0x90, 0x35, 0x59, 0x2f, 0xc5, 0x6b, 0xb1, 0xff, 0x10, 0x32, 0x6f, 0x2d, 0x1a, - 0xac, 0xd6, 0xf6, 0x5f, 0xab, 0xf1, 0xa6, 0x8b, 0x9a, 0x80, 0x4a, 0xe6, 0x9c, 0xb2, 0x64, 0x0e, - 0x44, 0x0d, 0xc8, 0xba, 0xd8, 0xd9, 0x37, 0xdb, 0x98, 0xe7, 0xb5, 0x8a, 0x28, 0xb9, 0x6d, 0x3b, - 0x98, 0xc8, 0xdc, 0x62, 0x24, 0x91, 0x4c, 0xce, 0x23, 0xcb, 0xe4, 0x40, 0xf4, 0x01, 0xe4, 0xdb, - 0xb6, 0xb5, 0x63, 0x76, 0x36, 0xf4, 0x3e, 0xcf, 0x6c, 0xe7, 0x54, 0x52, 0xaf, 0x06, 0x44, 0x7c, - 0x3e, 0x14, 0x3c, 0xc6, 0xe6, 0x43, 0x21, 0x55, 0xe4, 0xd0, 0x7f, 0xa5, 0x00, 0x22, 0xe7, 0xa0, - 0xb7, 0xa0, 0x80, 0x0f, 0x70, 0xdb, 0xf7, 0x6c, 0x3a, 0x33, 0xd5, 0xa2, 0x51, 0x6b, 0x00, 0x96, - 0xb6, 0x0f, 0x44, 0x50, 0xb2, 0xc7, 0x2d, 0xbd, 0x87, 0xdd, 0xbe, 0xde, 0x0e, 0x66, 0xb4, 0x74, - 0x31, 0x21, 0x50, 0xdc, 0xe3, 0x21, 0x10, 0xbd, 0x08, 0x29, 0x3a, 0xd5, 0x65, 0xe3, 0x59, 0x34, - 0x1c, 0x54, 0x8a, 0x96, 0x3c, 0xcf, 0xa5, 0x78, 0xf4, 0x1e, 0x4c, 0xef, 0x85, 0x81, 0x47, 0xd6, - 0x96, 0xa2, 0x0c, 0xb4, 0x48, 0x8e, 0x10, 0xd2, 0xea, 0xa6, 0x44, 0x38, 0xda, 0x81, 0x82, 0x6e, - 0x59, 0xb6, 0x47, 0x3f, 0x5f, 0xc1, 0xc8, 0xf6, 0xd2, 0xb8, 0x30, 0xad, 0xad, 0x46, 0xb4, 0xac, - 0xec, 0xa2, 0x79, 0x47, 0x90, 0x20, 0xe6, 0x1d, 0x01, 0x8c, 0x1a, 0x90, 0xe9, 0xea, 0x2d, 0xdc, - 0x0d, 0xbe, 0x17, 0x2f, 0x8c, 0x55, 0x71, 0x9b, 0x92, 0x31, 0xe9, 0x74, 0x30, 0xcc, 0xf8, 0xc4, - 0xc1, 0x30, 0x83, 0x2c, 0xee, 0x40, 0x29, 0xbe, 0x9e, 0xc9, 0xca, 0x8c, 0x4b, 0x62, 0x99, 0x91, - 0x3f, 0xb2, 0xb2, 0xd1, 0xa1, 0x20, 0x2c, 0xea, 0x24, 0x54, 0x54, 0x7f, 0xab, 0xc1, 0x9c, 0x6a, - 0xef, 0xa2, 0x0d, 0x61, 0xc7, 0x6b, 0x7c, 0xfc, 0xa4, 0x08, 0x75, 0xce, 0x3b, 0x66, 0xab, 0x47, - 0x1b, 0xbd, 0x0e, 0x45, 0xcb, 0x36, 0x70, 0x53, 0x27, 0x0a, 0xba, 0xa6, 0xeb, 0x95, 0x13, 0x74, - 0xa4, 0x4f, 0xc7, 0x56, 0x04, 0xb3, 0x1a, 0x20, 0x04, 0xee, 0x69, 0x09, 0x51, 0xfd, 0x04, 0x66, - 0x62, 0x43, 0x65, 0xa9, 0xe8, 0x49, 0x4c, 0x58, 0xf4, 0x44, 0x5f, 0xa2, 0xe4, 0x51, 0x5f, 0x22, - 0xf6, 0x05, 0xa9, 0xfe, 0x3c, 0x01, 0x05, 0xa1, 0xc3, 0x47, 0x0f, 0x61, 0x86, 0x7f, 0x15, 0x4d, - 0xab, 0xc3, 0x3a, 0xc9, 0x04, 0x1f, 0x37, 0x8d, 0x9c, 0xb8, 0xac, 0xdb, 0xad, 0xad, 0x90, 0x96, - 0x36, 0x92, 0xf4, 0x1b, 0xe6, 0x4a, 0x30, 0xf1, 0x1b, 0x26, 0x63, 0xd0, 0x03, 0x58, 0xf0, 0xfb, - 0xa4, 0xbf, 0x6d, 0xba, 0xfc, 0xec, 0xa2, 0x69, 0xf9, 0xbd, 0x16, 0x76, 0xe8, 0xea, 0xd3, 0xac, - 0xe3, 0x62, 0x14, 0xc1, 0xe1, 0xc6, 0x1d, 0x8a, 0x17, 0x3b, 0x2e, 0x15, 0x5e, 0xb0, 0x43, 0x6a, - 0x42, 0x3b, 0xdc, 0x04, 0x34, 0x3a, 0xd5, 0x97, 0x7c, 0xa0, 0x4d, 0xe6, 0x83, 0xea, 0x01, 0x94, - 0xe2, 0xb3, 0xfa, 0xa7, 0xe4, 0xcb, 0x3d, 0xc8, 0x87, 0x93, 0x76, 0xf4, 0x0a, 0x64, 0x1c, 0xac, - 0xbb, 0xb6, 0xc5, 0x77, 0x0b, 0xdd, 0xf6, 0x0c, 0x22, 0x6e, 0x7b, 0x06, 0x79, 0x0c, 0x65, 0xf7, - 0x61, 0x8a, 0x19, 0xe9, 0xba, 0xd9, 0xf5, 0xb0, 0x83, 0xae, 0x41, 0xc6, 0xf5, 0x74, 0x0f, 0xbb, - 0x65, 0x6d, 0x39, 0x79, 0xb1, 0x78, 0x65, 0x61, 0x74, 0x8c, 0x4e, 0xd0, 0x6c, 0x1d, 0x8c, 0x52, - 0x5c, 0x07, 0x83, 0x54, 0x7f, 0xa6, 0xc1, 0x94, 0x78, 0x5a, 0xf0, 0x64, 0xc4, 0x1e, 0xcf, 0x18, - 0x24, 0x71, 0x4c, 0x89, 0x87, 0x0a, 0x27, 0x67, 0x4b, 0xf2, 0x15, 0x64, 0x47, 0x12, 0x4d, 0xdf, - 0xc5, 0x0e, 0x8f, 0x56, 0xfa, 0x15, 0x64, 0xe0, 0x6d, 0x57, 0x8a, 0x76, 0x88, 0xa0, 0xdc, 0x0d, - 0x64, 0xad, 0xe2, 0x11, 0x05, 0xea, 0x44, 0x83, 0x20, 0xb2, 0xc9, 0x5c, 0x9a, 0x8c, 0x26, 0x1d, - 0x04, 0xd1, 0x94, 0x25, 0xb1, 0x8b, 0x29, 0x4b, 0x42, 0x3c, 0x46, 0xc8, 0x7c, 0x9d, 0xa6, 0x6b, - 0x8d, 0x8e, 0x1c, 0x62, 0x35, 0x40, 0xf2, 0x18, 0x35, 0xc0, 0xab, 0x90, 0xa5, 0x49, 0x37, 0xdc, - 0xe2, 0xd4, 0x27, 0x04, 0x24, 0x1f, 0xb7, 0x32, 0xc8, 0x23, 0x52, 0x4d, 0xfa, 0x07, 0xa6, 0x9a, - 0x26, 0x9c, 0xdd, 0xd5, 0xdd, 0x66, 0x90, 0x1c, 0x8d, 0xa6, 0xee, 0x35, 0xc3, 0xbd, 0x9e, 0xa1, - 0x7d, 0x04, 0x1d, 0x62, 0xee, 0xea, 0xee, 0x56, 0x40, 0xb3, 0xea, 0x6d, 0x8e, 0xee, 0xfc, 0x05, - 0x35, 0x05, 0xda, 0x86, 0x79, 0xb5, 0xf0, 0x2c, 0x5d, 0x39, 0x9d, 0xb1, 0xbb, 0x8f, 0x94, 0x3c, - 0xab, 0x40, 0xa3, 0xcf, 0x35, 0x28, 0x93, 0xaf, 0xa0, 0x83, 0x3f, 0xf6, 0x4d, 0x07, 0xf7, 0x48, - 0x58, 0x34, 0xed, 0x7d, 0xec, 0x74, 0xf5, 0x43, 0x7e, 0x5c, 0x75, 0x7e, 0x34, 0xe5, 0x6f, 0xda, - 0x46, 0x43, 0x60, 0x60, 0xaf, 0xd6, 0x97, 0x81, 0x77, 0x99, 0x10, 0xf1, 0xd5, 0xd4, 0x14, 0x42, - 0x08, 0xc1, 0x31, 0x06, 0x63, 0x85, 0x23, 0x07, 0x63, 0x2f, 0x42, 0xaa, 0x6f, 0xdb, 0x5d, 0xda, - 0xc6, 0xf1, 0x4a, 0x8f, 0x3c, 0x8b, 0x95, 0x1e, 0x79, 0x16, 0x67, 0x17, 0xeb, 0xa9, 0x5c, 0xae, - 0x94, 0x27, 0x9f, 0xc3, 0xa2, 0x7c, 0xc2, 0x35, 0xba, 0xa1, 0x92, 0x27, 0xbe, 0xa1, 0x52, 0xc7, - 0xb0, 0x46, 0x7a, 0x62, 0x6b, 0x64, 0x26, 0xb7, 0x46, 0xf5, 0x8b, 0x04, 0x4c, 0x4b, 0x87, 0x70, - 0x3f, 0x4d, 0x33, 0xfc, 0x2a, 0x01, 0x0b, 0xea, 0x57, 0x3a, 0x91, 0x56, 0xf4, 0x26, 0x90, 0xa2, - 0xf2, 0x56, 0x54, 0x74, 0xcd, 0x8f, 0x74, 0xa2, 0xd4, 0x9c, 0x41, 0x45, 0x3a, 0x72, 0x8e, 0x17, - 0xb0, 0xa3, 0x07, 0x50, 0x30, 0x85, 0x13, 0xc3, 0xa4, 0xea, 0x60, 0x47, 0x3c, 0x27, 0x64, 0xa3, - 0x8e, 0x31, 0xa7, 0x83, 0xa2, 0xa8, 0x7a, 0x06, 0x52, 0xa4, 0x2a, 0xac, 0xee, 0x43, 0x96, 0x2f, - 0x07, 0xbd, 0x0e, 0x79, 0x9a, 0x8b, 0x69, 0x77, 0xc5, 0x4a, 0x78, 0x5a, 0xde, 0x10, 0x60, 0xec, - 0xc6, 0x4c, 0x2e, 0x80, 0xa1, 0xff, 0x02, 0x20, 0xe9, 0x87, 0x67, 0xe1, 0x04, 0xcd, 0x65, 0xb4, - 0x8b, 0xeb, 0xdb, 0xc6, 0x48, 0xea, 0xcd, 0x87, 0xc0, 0xea, 0xef, 0x13, 0x50, 0x10, 0xcf, 0x28, - 0x1f, 0x4b, 0xf9, 0xa7, 0x10, 0x74, 0xd8, 0x4d, 0xdd, 0x30, 0xc8, 0x5f, 0x1c, 0x7c, 0x28, 0x57, - 0xc6, 0x1a, 0x29, 0xf8, 0x7f, 0x35, 0xe0, 0x60, 0xfd, 0x14, 0xbd, 0x87, 0x61, 0xc6, 0x50, 0x82, - 0xd6, 0x52, 0x1c, 0xb7, 0xb8, 0x07, 0xf3, 0x4a, 0x51, 0x62, 0x17, 0x94, 0x7e, 0x52, 0x5d, 0xd0, - 0x6f, 0xd2, 0x30, 0xaf, 0x3c, 0x1b, 0x8e, 0x45, 0x70, 0xf2, 0x89, 0x44, 0xf0, 0x2f, 0x34, 0x95, - 0x65, 0xd9, 0xc1, 0xd0, 0x5b, 0x13, 0x1c, 0x58, 0x3f, 0x29, 0x1b, 0xcb, 0x61, 0x91, 0x7e, 0xac, - 0x98, 0xcc, 0x4c, 0x1a, 0x93, 0xe8, 0x32, 0x6b, 0x28, 0xa9, 0x2e, 0x76, 0x6c, 0x13, 0xec, 0xd0, - 0x98, 0xaa, 0x2c, 0x07, 0xa1, 0xf7, 0x60, 0x3a, 0xe0, 0x60, 0x63, 0x8c, 0x5c, 0x34, 0x63, 0xe0, - 0x34, 0xf1, 0x49, 0xc6, 0x94, 0x08, 0x17, 0xb2, 0x64, 0xfe, 0x18, 0x59, 0x12, 0x8e, 0xca, 0x92, - 0x4f, 0x35, 0x36, 0xa5, 0x54, 0x3b, 0xd0, 0x60, 0x26, 0x76, 0x25, 0xe3, 0x47, 0xff, 0xcd, 0x91, - 0x5e, 0xf0, 0x33, 0x0d, 0xf2, 0xe1, 0x8d, 0x1f, 0xb4, 0x0a, 0x19, 0xcc, 0x6e, 0x8d, 0xb0, 0xb4, - 0x33, 0x1b, 0xbb, 0xd1, 0x47, 0x70, 0xfc, 0x0e, 0x5f, 0xec, 0xa2, 0x48, 0x83, 0x33, 0x3e, 0x46, - 0x01, 0xfe, 0x07, 0x2d, 0x28, 0xc0, 0x47, 0x56, 0x91, 0xfc, 0xe1, 0xab, 0x38, 0x39, 0xd3, 0x7d, - 0x0f, 0x90, 0xa6, 0x6b, 0x21, 0x8d, 0xb4, 0x87, 0x9d, 0x9e, 0x69, 0xe9, 0x5d, 0x1a, 0x8a, 0x39, - 0xb6, 0xab, 0x03, 0x98, 0xb8, 0xab, 0x03, 0x18, 0xda, 0x85, 0x99, 0x68, 0x3c, 0x47, 0xc5, 0xa8, - 0xaf, 0x10, 0xbe, 0x2f, 0x13, 0xb1, 0xa3, 0x87, 0x18, 0xa7, 0x7c, 0x07, 0x20, 0x86, 0x44, 0x06, - 0x14, 0xdb, 0xb6, 0xe5, 0xe9, 0xa6, 0x85, 0x1d, 0xa6, 0x28, 0xa9, 0xba, 0x42, 0x75, 0x55, 0xa2, - 0x61, 0x43, 0x13, 0x99, 0x4f, 0xbe, 0x42, 0x25, 0xe3, 0xd0, 0x47, 0x30, 0x1d, 0x34, 0x42, 0x4c, - 0x49, 0x4a, 0x75, 0x85, 0x6a, 0x4d, 0x24, 0x61, 0x9b, 0x41, 0xe2, 0x92, 0xaf, 0x50, 0x49, 0x28, - 0xf4, 0x21, 0x4c, 0x75, 0x49, 0x87, 0xb6, 0x76, 0xd0, 0x37, 0x1d, 0x6c, 0xa8, 0x2f, 0xf5, 0xdd, - 0x16, 0x28, 0x58, 0xe2, 0x12, 0x79, 0xe4, 0xbb, 0x0c, 0x22, 0x86, 0xf8, 0xa3, 0xa7, 0x1f, 0x34, - 0x7c, 0xcb, 0x5d, 0x3b, 0xe0, 0x17, 0xb4, 0xb2, 0x2a, 0x7f, 0x6c, 0xc8, 0x44, 0xcc, 0x1f, 0x31, - 0x4e, 0xd9, 0x1f, 0x31, 0x24, 0xba, 0x4d, 0xf3, 0x32, 0x33, 0x12, 0xbb, 0xdc, 0xb7, 0x30, 0x52, - 0x50, 0x31, 0xfb, 0xb0, 0x71, 0x0c, 0x7f, 0x92, 0x84, 0x86, 0x12, 0x50, 0x17, 0x4a, 0x7d, 0xdb, - 0xa0, 0xaf, 0xdd, 0xc0, 0x9e, 0xef, 0x58, 0xd8, 0xe0, 0x8d, 0xd2, 0xd2, 0x88, 0x54, 0x89, 0x8a, - 0x7d, 0xbe, 0xe2, 0xbc, 0xf2, 0x55, 0xcd, 0x38, 0x16, 0x7d, 0x0a, 0x73, 0xb1, 0xab, 0x4a, 0xec, - 0x3d, 0x0a, 0xaa, 0x23, 0x8a, 0x75, 0x05, 0x25, 0xeb, 0x69, 0x55, 0x32, 0x24, 0xcd, 0x4a, 0x2d, - 0x44, 0x7b, 0x47, 0xb7, 0x3a, 0xeb, 0x76, 0x6b, 0xdb, 0xe2, 0x4d, 0xa0, 0xde, 0xea, 0x62, 0x7e, - 0x5b, 0x2f, 0xa6, 0xfd, 0x86, 0x82, 0x92, 0x69, 0x57, 0xc9, 0x90, 0xb5, 0xab, 0x28, 0xc2, 0x6b, - 0x49, 0xa4, 0xac, 0x08, 0xaf, 0xef, 0xa9, 0xae, 0x25, 0x31, 0x02, 0xe1, 0x5a, 0x12, 0x03, 0x28, - 0xae, 0x25, 0x31, 0x04, 0xbb, 0xd1, 0xd6, 0xb6, 0xad, 0xb6, 0xd9, 0x35, 0xe9, 0x88, 0x9b, 0x19, - 0xb5, 0xa8, 0xbe, 0xd1, 0x36, 0x42, 0x18, 0xdc, 0x68, 0x1b, 0x41, 0xc4, 0x6f, 0xb4, 0x8d, 0x10, - 0xa0, 0x9b, 0x50, 0xda, 0xd1, 0xcd, 0xae, 0xef, 0xe0, 0x66, 0x5b, 0xf7, 0x70, 0xc7, 0x76, 0x0e, - 0xf9, 0xc1, 0x1f, 0x8d, 0x6b, 0x8e, 0xbb, 0xca, 0x51, 0xe2, 0x11, 0x67, 0x0c, 0x85, 0xee, 0xc1, - 0x6c, 0x20, 0xc9, 0xf5, 0x5b, 0xa1, 0xb0, 0xd3, 0x54, 0x18, 0xbd, 0x87, 0xcc, 0xd1, 0x5b, 0x11, - 0x56, 0x90, 0x87, 0x46, 0xb1, 0xf5, 0x5c, 0x30, 0xe0, 0x5a, 0x4f, 0xe5, 0xd2, 0xa5, 0xcc, 0x7a, - 0x2a, 0x07, 0xa5, 0x02, 0x3f, 0x57, 0xbc, 0x07, 0x33, 0xb1, 0xcc, 0x88, 0xde, 0x85, 0xf0, 0x56, - 0xd0, 0xfd, 0xc3, 0x7e, 0x50, 0x76, 0x4b, 0xb7, 0x88, 0x08, 0x5c, 0x75, 0x8b, 0x88, 0xc0, 0xab, - 0x5f, 0xa6, 0x20, 0x17, 0x6c, 0xbd, 0x13, 0x69, 0xa4, 0x56, 0x20, 0xdb, 0xc3, 0x2e, 0xbd, 0xf9, - 0x93, 0x88, 0xea, 0x31, 0x0e, 0x12, 0xeb, 0x31, 0x0e, 0x92, 0xcb, 0xc5, 0xe4, 0x63, 0x95, 0x8b, - 0xa9, 0x89, 0xcb, 0x45, 0x4c, 0x0f, 0xbb, 0x85, 0x94, 0x1e, 0x9c, 0x11, 0x3d, 0xfa, 0x3b, 0x11, - 0x1c, 0x85, 0x8b, 0x8c, 0xb1, 0xa3, 0x70, 0x11, 0x85, 0xf6, 0xe0, 0xb4, 0x70, 0x8e, 0xc5, 0x07, - 0x98, 0x24, 0x95, 0x17, 0xc7, 0xdf, 0x2c, 0x68, 0x50, 0x2a, 0x96, 0xb0, 0xf6, 0x62, 0x50, 0xb1, - 0xde, 0x8e, 0xe3, 0x48, 0x48, 0x18, 0xb8, 0xe5, 0x77, 0x36, 0xb8, 0xd9, 0xb3, 0x51, 0x48, 0x88, - 0x70, 0x31, 0x24, 0x44, 0x78, 0xf5, 0x9f, 0x09, 0x28, 0xca, 0xef, 0x7b, 0x22, 0x81, 0xf1, 0x3a, - 0xe4, 0xf1, 0x81, 0xe9, 0x35, 0xdb, 0xb6, 0x81, 0x79, 0xd3, 0x49, 0xfd, 0x4c, 0x80, 0x57, 0x6d, - 0x43, 0xf2, 0x73, 0x00, 0x13, 0xa3, 0x29, 0x39, 0x51, 0x34, 0x45, 0xf3, 0xe2, 0xd4, 0x04, 0xf3, - 0x62, 0xa5, 0x9f, 0xf2, 0x27, 0xe3, 0xa7, 0xea, 0x37, 0x09, 0x28, 0xc5, 0xbf, 0x4f, 0xcf, 0xc6, - 0x16, 0x94, 0x77, 0x53, 0x72, 0xe2, 0xdd, 0xf4, 0x1e, 0x4c, 0x93, 0xa2, 0x52, 0xf7, 0x3c, 0x7e, - 0x51, 0x38, 0x45, 0xeb, 0x42, 0x96, 0x8d, 0x7c, 0x6b, 0x35, 0x80, 0x4b, 0xd9, 0x48, 0x80, 0x8f, - 0x84, 0x6e, 0xfa, 0x98, 0xa1, 0xfb, 0x79, 0x02, 0xa6, 0x37, 0x6d, 0xe3, 0x3e, 0xab, 0x37, 0xbd, - 0x67, 0xc5, 0x9e, 0x4f, 0x33, 0xa5, 0x55, 0x67, 0x60, 0x5a, 0x2a, 0x38, 0xab, 0x5f, 0xb0, 0x38, - 0x93, 0xbf, 0xeb, 0x3f, 0x3d, 0xbb, 0x14, 0x61, 0x4a, 0xac, 0x93, 0xab, 0x75, 0x98, 0x89, 0x95, - 0xb5, 0xe2, 0x0b, 0x68, 0x93, 0xbc, 0x40, 0xf5, 0x1a, 0xcc, 0xa9, 0xea, 0x3d, 0x21, 0xeb, 0x68, - 0x13, 0x1c, 0x72, 0xdd, 0x80, 0x39, 0x55, 0xdd, 0x76, 0xfc, 0xe5, 0xbc, 0xcb, 0x0f, 0x90, 0x79, - 0x85, 0x75, 0x6c, 0xfe, 0xeb, 0x30, 0xab, 0xa8, 0xb4, 0x8e, 0x2f, 0xe7, 0xaf, 0xe1, 0x00, 0x21, - 0xba, 0xdc, 0x7f, 0x1d, 0x4a, 0xfd, 0xe0, 0xa1, 0xc9, 0xdb, 0xd4, 0x74, 0x74, 0xdb, 0x2a, 0xc4, - 0xad, 0xc7, 0xfa, 0xd5, 0xa2, 0x8c, 0x91, 0xe5, 0xf0, 0x16, 0x36, 0xa3, 0x90, 0xd3, 0x88, 0xf5, - 0xb2, 0x45, 0x19, 0x23, 0xb8, 0x28, 0x7b, 0xb4, 0x8b, 0x68, 0x0b, 0x9c, 0xae, 0x7e, 0xa6, 0xc1, - 0x4c, 0xec, 0xc7, 0x07, 0xe8, 0x32, 0xe4, 0xe8, 0x2f, 0x03, 0xa3, 0xe6, 0x9f, 0x5a, 0x87, 0xc2, - 0xa4, 0x05, 0x64, 0x39, 0x08, 0xbd, 0x01, 0xf9, 0xf0, 0xf7, 0x08, 0xfc, 0x08, 0x9a, 0xc5, 0x6f, - 0x00, 0x94, 0xe2, 0x37, 0x00, 0xf2, 0xb9, 0xc1, 0xff, 0xc3, 0xd9, 0xb1, 0xbf, 0x44, 0x38, 0xd6, - 0x71, 0x67, 0x34, 0x00, 0x48, 0x1d, 0x6b, 0x00, 0x70, 0x00, 0x0b, 0xea, 0x1f, 0x08, 0x08, 0xda, - 0x13, 0x47, 0x6a, 0x8f, 0xac, 0x9f, 0x9c, 0xd0, 0xfa, 0x89, 0xea, 0x1e, 0x9d, 0x98, 0x84, 0x17, - 0xf1, 0xd1, 0x25, 0x48, 0xf7, 0x6d, 0xbb, 0xeb, 0xf2, 0x3b, 0x1e, 0x54, 0x1d, 0x05, 0x88, 0xea, - 0x28, 0xe0, 0x31, 0xe6, 0x33, 0x7e, 0x10, 0xc1, 0xd1, 0xcf, 0x0a, 0x9e, 0x82, 0x75, 0x5f, 0xbe, - 0x0c, 0xb9, 0xe0, 0x1c, 0x1d, 0x01, 0x64, 0xee, 0x6d, 0xaf, 0x6d, 0xaf, 0x5d, 0x2b, 0x9d, 0x42, - 0x05, 0xc8, 0x6e, 0xae, 0xdd, 0xb9, 0x76, 0xeb, 0xce, 0x8d, 0x92, 0x46, 0x1e, 0x1a, 0xdb, 0x77, - 0xee, 0x90, 0x87, 0xc4, 0xcb, 0xb7, 0xc5, 0xbb, 0x79, 0xbc, 0x02, 0x9c, 0x82, 0xdc, 0x6a, 0xbf, - 0x4f, 0x37, 0x2f, 0xe3, 0x5d, 0xdb, 0x37, 0x49, 0x46, 0x28, 0x69, 0x28, 0x0b, 0xc9, 0xbb, 0x77, - 0x37, 0x4a, 0x09, 0x34, 0x07, 0xa5, 0x6b, 0x58, 0x37, 0xba, 0xa6, 0x85, 0x83, 0xfc, 0x57, 0x4a, - 0xd6, 0x1f, 0xfe, 0xe9, 0xdb, 0x25, 0xed, 0x9b, 0x6f, 0x97, 0xb4, 0x7f, 0x7c, 0xbb, 0xa4, 0x7d, - 0xf9, 0xdd, 0xd2, 0xa9, 0x6f, 0xbe, 0x5b, 0x3a, 0xf5, 0xb7, 0xef, 0x96, 0x4e, 0xfd, 0xdf, 0xe5, - 0x8e, 0xe9, 0xed, 0xfa, 0xad, 0x5a, 0xdb, 0xee, 0xf1, 0x9f, 0x38, 0xf7, 0x1d, 0x9b, 0x24, 0x1a, - 0xfe, 0xb4, 0x12, 0xff, 0xed, 0xf3, 0xef, 0x12, 0xe7, 0x56, 0xe9, 0xe3, 0x26, 0xa3, 0xab, 0xdd, - 0xb2, 0x6b, 0x0c, 0x40, 0x7f, 0xed, 0xea, 0xb6, 0x32, 0xf4, 0x57, 0xad, 0xaf, 0xff, 0x3b, 0x00, - 0x00, 0xff, 0xff, 0xd3, 0x8d, 0xc0, 0xbf, 0x36, 0x3d, 0x00, 0x00, + 0xfd, 0xce, 0x23, 0x9d, 0xa1, 0xab, 0xf0, 0xa2, 0x33, 0x94, 0x04, 0x8b, 0xbf, 0xd1, 0x60, 0x71, + 0xbc, 0x9f, 0xd1, 0x05, 0x48, 0xee, 0xe1, 0x43, 0xde, 0x93, 0x9d, 0x1e, 0x0e, 0x2a, 0xd3, 0x7b, + 0xf8, 0x50, 0x90, 0x4a, 0xb0, 0xe8, 0x7f, 0x21, 0xbd, 0xaf, 0x77, 0x7d, 0xcc, 0x4b, 0xfe, 0x5a, + 0x8d, 0xb5, 0x93, 0x35, 0xb1, 0x9d, 0xac, 0xf5, 0xf7, 0x3a, 0x04, 0x50, 0x0b, 0xac, 0x50, 0xbb, + 0xe7, 0xeb, 0x96, 0x67, 0x7a, 0x87, 0xcc, 0x76, 0x54, 0x80, 0x68, 0x3b, 0x0a, 0x78, 0x3b, 0xf1, + 0xa6, 0xb6, 0xf8, 0x6b, 0x0d, 0xce, 0x8e, 0xf5, 0xf7, 0x33, 0xb1, 0x42, 0x62, 0xc4, 0xf1, 0xfe, + 0x79, 0x16, 0x96, 0xb8, 0x9e, 0xca, 0x69, 0xa5, 0xc4, 0x7a, 0x2a, 0x97, 0x28, 0x25, 0xab, 0xdf, + 0x67, 0x20, 0x1f, 0x36, 0x78, 0xe8, 0x26, 0x94, 0x0c, 0x6c, 0xf8, 0xfd, 0xae, 0xd9, 0xa6, 0x91, + 0x46, 0x82, 0x9a, 0x75, 0xd4, 0x34, 0xbb, 0x4a, 0x38, 0x29, 0xbc, 0x67, 0x62, 0x28, 0x74, 0x05, + 0x72, 0xbc, 0x91, 0x39, 0xa4, 0x79, 0x6d, 0xba, 0xbe, 0x30, 0x1c, 0x54, 0x50, 0x00, 0x13, 0x58, + 0x43, 0x3a, 0xd4, 0x00, 0x60, 0x93, 0x81, 0x0d, 0xec, 0xe9, 0xbc, 0xa5, 0x2a, 0xcb, 0xbb, 0xe1, + 0x6e, 0x88, 0x67, 0x3d, 0x7e, 0x44, 0x2f, 0xf6, 0xf8, 0x11, 0x14, 0x7d, 0x08, 0xd0, 0xd3, 0x4d, + 0x8b, 0xf1, 0xf1, 0xfe, 0xa9, 0x3a, 0x2e, 0xc3, 0x6e, 0x84, 0x94, 0x4c, 0x7a, 0xc4, 0x29, 0x4a, + 0x8f, 0xa0, 0xe8, 0x2e, 0x64, 0xf9, 0x2c, 0xa3, 0x9c, 0xa1, 0x9b, 0x77, 0x69, 0x9c, 0x68, 0x2e, + 0x96, 0x76, 0xe3, 0x9c, 0x45, 0xec, 0xc6, 0x39, 0x88, 0x98, 0xad, 0x6b, 0xee, 0x60, 0xcf, 0xec, + 0x61, 0x9a, 0x4d, 0xb8, 0xd9, 0x02, 0x98, 0x68, 0xb6, 0x00, 0x86, 0xde, 0x04, 0xd0, 0xbd, 0x0d, + 0xdb, 0xf5, 0xee, 0x5a, 0x6d, 0x4c, 0x3b, 0xa2, 0x1c, 0x5b, 0x7e, 0x04, 0x15, 0x97, 0x1f, 0x41, + 0xd1, 0x3b, 0x50, 0xe8, 0xf3, 0x2f, 0x70, 0xab, 0x8b, 0x69, 0xc7, 0x93, 0x63, 0x05, 0x83, 0x00, + 0x16, 0x78, 0x45, 0x6a, 0x74, 0x03, 0x66, 0xda, 0xb6, 0xd5, 0xf6, 0x1d, 0x07, 0x5b, 0xed, 0xc3, + 0x2d, 0x7d, 0x07, 0xd3, 0xee, 0x26, 0xc7, 0x42, 0x25, 0x86, 0x12, 0x43, 0x25, 0x86, 0x42, 0x6f, + 0x40, 0x3e, 0x9c, 0x0c, 0xd1, 0x06, 0x26, 0xcf, 0x07, 0x0d, 0x01, 0x50, 0x60, 0x8e, 0x28, 0xc9, + 0xe2, 0x4d, 0xf7, 0x1a, 0x0f, 0x3a, 0x4c, 0x9b, 0x12, 0xbe, 0x78, 0x01, 0x2c, 0x2e, 0x5e, 0x00, + 0x0b, 0xf9, 0xbd, 0x78, 0x64, 0x7e, 0xbf, 0x0e, 0x25, 0x7c, 0xc0, 0xa6, 0x5b, 0x4d, 0xc2, 0xe4, + 0x3b, 0x26, 0xad, 0xe7, 0xf3, 0xac, 0x93, 0x0a, 0x70, 0xeb, 0x76, 0x6b, 0xdb, 0x31, 0x05, 0xf6, + 0xa2, 0x8c, 0x09, 0xb7, 0xdd, 0x74, 0xa9, 0xb8, 0x9e, 0xca, 0xcd, 0x94, 0x4a, 0xd5, 0xbf, 0x68, + 0x30, 0xa7, 0x8a, 0xbe, 0xd8, 0x4e, 0xd0, 0x9e, 0xc8, 0x4e, 0xf8, 0x00, 0x72, 0x7d, 0xdb, 0x68, + 0xba, 0x7d, 0xdc, 0xe6, 0x79, 0x25, 0xb6, 0x0f, 0x36, 0x6d, 0x63, 0xab, 0x8f, 0xdb, 0xff, 0x63, + 0x7a, 0xbb, 0xab, 0xfb, 0xb6, 0x69, 0xdc, 0x36, 0x5d, 0x1e, 0xb0, 0x7d, 0x86, 0x91, 0x8a, 0x9d, + 0x2c, 0x07, 0xd6, 0x73, 0x90, 0x61, 0x5a, 0xaa, 0x7f, 0x4d, 0x42, 0x29, 0x1e, 0xf1, 0x3f, 0xa6, + 0x57, 0x41, 0x0f, 0x20, 0x6b, 0xb2, 0x5e, 0x8a, 0xd7, 0x62, 0xff, 0x21, 0x64, 0xde, 0x5a, 0x34, + 0x58, 0xad, 0xed, 0xbf, 0x56, 0xe3, 0x4d, 0x17, 0x35, 0x01, 0x95, 0xcc, 0x39, 0x65, 0xc9, 0x1c, + 0x88, 0x1a, 0x90, 0x75, 0xb1, 0xb3, 0x6f, 0xb6, 0x31, 0xcf, 0x6b, 0x15, 0x51, 0x72, 0xdb, 0x76, + 0x30, 0x91, 0xb9, 0xc5, 0x48, 0x22, 0x99, 0x9c, 0x47, 0x96, 0xc9, 0x81, 0xe8, 0x03, 0xc8, 0xb7, + 0x6d, 0x6b, 0xc7, 0xec, 0x6c, 0xe8, 0x7d, 0x9e, 0xd9, 0xce, 0xa9, 0xa4, 0x5e, 0x0d, 0x88, 0xf8, + 0x7c, 0x28, 0x78, 0x8c, 0xcd, 0x87, 0x42, 0xaa, 0xc8, 0xa1, 0xff, 0x4a, 0x01, 0x44, 0xce, 0x41, + 0x6f, 0x41, 0x01, 0x1f, 0xe0, 0xb6, 0xef, 0xd9, 0x74, 0x66, 0xaa, 0x45, 0xa3, 0xd6, 0x00, 0x2c, + 0x6d, 0x1f, 0x88, 0xa0, 0x64, 0x8f, 0x5b, 0x7a, 0x0f, 0xbb, 0x7d, 0xbd, 0x1d, 0xcc, 0x68, 0xe9, + 0x62, 0x42, 0xa0, 0xb8, 0xc7, 0x43, 0x20, 0x7a, 0x11, 0x52, 0x74, 0xaa, 0xcb, 0xc6, 0xb3, 0x68, + 0x38, 0xa8, 0x14, 0x2d, 0x79, 0x9e, 0x4b, 0xf1, 0xe8, 0x3d, 0x98, 0xde, 0x0b, 0x03, 0x8f, 0xac, + 0x2d, 0x45, 0x19, 0x68, 0x91, 0x1c, 0x21, 0xa4, 0xd5, 0x4d, 0x89, 0x70, 0xb4, 0x03, 0x05, 0xdd, + 0xb2, 0x6c, 0x8f, 0x7e, 0xbe, 0x82, 0x91, 0xed, 0xa5, 0x71, 0x61, 0x5a, 0x5b, 0x8d, 0x68, 0x59, + 0xd9, 0x45, 0xf3, 0x8e, 0x20, 0x41, 0xcc, 0x3b, 0x02, 0x18, 0x35, 0x20, 0xd3, 0xd5, 0x5b, 0xb8, + 0x1b, 0x7c, 0x2f, 0x5e, 0x18, 0xab, 0xe2, 0x36, 0x25, 0x63, 0xd2, 0xe9, 0x60, 0x98, 0xf1, 0x89, + 0x83, 0x61, 0x06, 0x59, 0xdc, 0x81, 0x52, 0x7c, 0x3d, 0x93, 0x95, 0x19, 0x97, 0xc4, 0x32, 0x23, + 0x7f, 0x64, 0x65, 0xa3, 0x43, 0x41, 0x58, 0xd4, 0x49, 0xa8, 0xa8, 0xfe, 0x4e, 0x83, 0x39, 0xd5, + 0xde, 0x45, 0x1b, 0xc2, 0x8e, 0xd7, 0xf8, 0xf8, 0x49, 0x11, 0xea, 0x9c, 0x77, 0xcc, 0x56, 0x8f, + 0x36, 0x7a, 0x1d, 0x8a, 0x96, 0x6d, 0xe0, 0xa6, 0x4e, 0x14, 0x74, 0x4d, 0xd7, 0x2b, 0x27, 0xe8, + 0x48, 0x9f, 0x8e, 0xad, 0x08, 0x66, 0x35, 0x40, 0x08, 0xdc, 0xd3, 0x12, 0xa2, 0xfa, 0x09, 0xcc, + 0xc4, 0x86, 0xca, 0x52, 0xd1, 0x93, 0x98, 0xb0, 0xe8, 0x89, 0xbe, 0x44, 0xc9, 0xa3, 0xbe, 0x44, + 0xec, 0x0b, 0x52, 0xfd, 0x79, 0x02, 0x0a, 0x42, 0x87, 0x8f, 0x1e, 0xc2, 0x0c, 0xff, 0x2a, 0x9a, + 0x56, 0x87, 0x75, 0x92, 0x09, 0x3e, 0x6e, 0x1a, 0x39, 0x71, 0x59, 0xb7, 0x5b, 0x5b, 0x21, 0x2d, + 0x6d, 0x24, 0xe9, 0x37, 0xcc, 0x95, 0x60, 0xe2, 0x37, 0x4c, 0xc6, 0xa0, 0x07, 0xb0, 0xe0, 0xf7, + 0x49, 0x7f, 0xdb, 0x74, 0xf9, 0xd9, 0x45, 0xd3, 0xf2, 0x7b, 0x2d, 0xec, 0xd0, 0xd5, 0xa7, 0x59, + 0xc7, 0xc5, 0x28, 0x82, 0xc3, 0x8d, 0x3b, 0x14, 0x2f, 0x76, 0x5c, 0x2a, 0xbc, 0x60, 0x87, 0xd4, + 0x84, 0x76, 0xb8, 0x09, 0x68, 0x74, 0xaa, 0x2f, 0xf9, 0x40, 0x9b, 0xcc, 0x07, 0xd5, 0x03, 0x28, + 0xc5, 0x67, 0xf5, 0x4f, 0xc9, 0x97, 0x7b, 0x90, 0x0f, 0x27, 0xed, 0xe8, 0x15, 0xc8, 0x38, 0x58, + 0x77, 0x6d, 0x8b, 0xef, 0x16, 0xba, 0xed, 0x19, 0x44, 0xdc, 0xf6, 0x0c, 0xf2, 0x18, 0xca, 0xee, + 0xc3, 0x14, 0x33, 0xd2, 0x75, 0xb3, 0xeb, 0x61, 0x07, 0x5d, 0x83, 0x8c, 0xeb, 0xe9, 0x1e, 0x76, + 0xcb, 0xda, 0x72, 0xf2, 0x62, 0xf1, 0xca, 0xc2, 0xe8, 0x18, 0x9d, 0xa0, 0xd9, 0x3a, 0x18, 0xa5, + 0xb8, 0x0e, 0x06, 0xa9, 0xfe, 0x4c, 0x83, 0x29, 0xf1, 0xb4, 0xe0, 0xc9, 0x88, 0x3d, 0x9e, 0x31, + 0x48, 0xe2, 0x98, 0x12, 0x0f, 0x15, 0x4e, 0xce, 0x96, 0xe4, 0x2b, 0xc8, 0x8e, 0x24, 0x9a, 0xbe, + 0x8b, 0x1d, 0x1e, 0xad, 0xf4, 0x2b, 0xc8, 0xc0, 0xdb, 0xae, 0x14, 0xed, 0x10, 0x41, 0xb9, 0x1b, + 0xc8, 0x5a, 0xc5, 0x23, 0x0a, 0xd4, 0x89, 0x06, 0x41, 0x64, 0x93, 0xb9, 0x34, 0x19, 0x4d, 0x3a, + 0x08, 0xa2, 0x29, 0x4b, 0x62, 0x17, 0x53, 0x96, 0x84, 0x78, 0x8c, 0x90, 0xf9, 0x26, 0x4d, 0xd7, + 0x1a, 0x1d, 0x39, 0xc4, 0x6a, 0x80, 0xe4, 0x31, 0x6a, 0x80, 0x57, 0x21, 0x4b, 0x93, 0x6e, 0xb8, + 0xc5, 0xa9, 0x4f, 0x08, 0x48, 0x3e, 0x6e, 0x65, 0x90, 0x47, 0xa4, 0x9a, 0xf4, 0x0f, 0x4c, 0x35, + 0x4d, 0x38, 0xbb, 0xab, 0xbb, 0xcd, 0x20, 0x39, 0x1a, 0x4d, 0xdd, 0x6b, 0x86, 0x7b, 0x3d, 0x43, + 0xfb, 0x08, 0x3a, 0xc4, 0xdc, 0xd5, 0xdd, 0xad, 0x80, 0x66, 0xd5, 0xdb, 0x1c, 0xdd, 0xf9, 0x0b, + 0x6a, 0x0a, 0xb4, 0x0d, 0xf3, 0x6a, 0xe1, 0x59, 0xba, 0x72, 0x3a, 0x63, 0x77, 0x1f, 0x29, 0x79, + 0x56, 0x81, 0x46, 0x9f, 0x6b, 0x50, 0x26, 0x5f, 0x41, 0x07, 0x7f, 0xec, 0x9b, 0x0e, 0xee, 0x91, + 0xb0, 0x68, 0xda, 0xfb, 0xd8, 0xe9, 0xea, 0x87, 0xfc, 0xb8, 0xea, 0xfc, 0x68, 0xca, 0xdf, 0xb4, + 0x8d, 0x86, 0xc0, 0xc0, 0x5e, 0xad, 0x2f, 0x03, 0xef, 0x32, 0x21, 0xe2, 0xab, 0xa9, 0x29, 0x84, + 0x10, 0x82, 0x63, 0x0c, 0xc6, 0x0a, 0x47, 0x0e, 0xc6, 0x5e, 0x84, 0x54, 0xdf, 0xb6, 0xbb, 0xb4, + 0x8d, 0xe3, 0x95, 0x1e, 0x79, 0x16, 0x2b, 0x3d, 0xf2, 0x8c, 0x5e, 0x87, 0x3c, 0x95, 0x69, 0x19, + 0xf8, 0x80, 0x1e, 0x12, 0xf1, 0xbc, 0x4c, 0xa4, 0x10, 0x98, 0x98, 0x97, 0x03, 0x98, 0x38, 0xf0, + 0x58, 0x4f, 0xe5, 0x72, 0xa5, 0x3c, 0xf9, 0x86, 0x16, 0xe5, 0x63, 0xb1, 0xd1, 0x5d, 0x98, 0x3c, + 0xf1, 0x5d, 0x98, 0x3a, 0x86, 0x09, 0xd3, 0x13, 0x9b, 0x30, 0xf3, 0x68, 0x13, 0x4a, 0xe3, 0x9f, + 0x2f, 0x12, 0x30, 0x2d, 0x9d, 0xdc, 0xfd, 0x34, 0xcd, 0xf0, 0xab, 0x04, 0x2c, 0xa8, 0x5f, 0xe9, + 0x44, 0xfa, 0xd7, 0x9b, 0x40, 0x2a, 0xd1, 0x5b, 0x51, 0xa5, 0x36, 0x3f, 0xd2, 0xbe, 0x52, 0x73, + 0x06, 0x65, 0xec, 0xc8, 0xe1, 0x5f, 0xc0, 0x8e, 0x1e, 0x40, 0xc1, 0x14, 0x8e, 0x19, 0x93, 0xaa, + 0xd3, 0x20, 0xf1, 0x70, 0x91, 0xcd, 0x47, 0xc6, 0x1c, 0x29, 0x8a, 0xa2, 0xea, 0x19, 0x48, 0x91, + 0x52, 0xb2, 0xba, 0x0f, 0x59, 0xbe, 0x1c, 0xb2, 0xf7, 0x68, 0x02, 0xa7, 0x2d, 0x19, 0xab, 0xfb, + 0xe9, 0xde, 0x23, 0xc0, 0xd8, 0x35, 0x9b, 0x5c, 0x00, 0x43, 0xff, 0x05, 0x40, 0x72, 0x16, 0x4f, + 0xdd, 0x09, 0x9a, 0x00, 0x69, 0xeb, 0xd7, 0xb7, 0x8d, 0x91, 0x7c, 0x9d, 0x0f, 0x81, 0xd5, 0x3f, + 0x24, 0xa0, 0x20, 0x1e, 0x6c, 0x3e, 0x96, 0xf2, 0x4f, 0x21, 0x68, 0xcb, 0x9b, 0xba, 0x61, 0x90, + 0xbf, 0x38, 0xf8, 0xba, 0xae, 0x8c, 0x35, 0x52, 0xf0, 0xff, 0x6a, 0xc0, 0xc1, 0x9a, 0x30, 0x7a, + 0x79, 0xc3, 0x8c, 0xa1, 0x04, 0xad, 0xa5, 0x38, 0x6e, 0x71, 0x0f, 0xe6, 0x95, 0xa2, 0xc4, 0xd6, + 0x29, 0xfd, 0xa4, 0x5a, 0xa7, 0xdf, 0xa6, 0x61, 0x5e, 0x79, 0xa0, 0x1c, 0x8b, 0xe0, 0xe4, 0x13, + 0x89, 0xe0, 0x5f, 0x68, 0x2a, 0xcb, 0xb2, 0xd3, 0xa4, 0xb7, 0x26, 0x38, 0xe5, 0x7e, 0x52, 0x36, + 0x96, 0xc3, 0x22, 0xfd, 0x58, 0x31, 0x99, 0x99, 0x34, 0x26, 0xd1, 0x65, 0xd6, 0x85, 0x52, 0x5d, + 0xec, 0xac, 0x27, 0xd8, 0xa1, 0x31, 0x55, 0x59, 0x0e, 0x42, 0xef, 0xc1, 0x74, 0xc0, 0xc1, 0x66, + 0x1f, 0xb9, 0x68, 0x30, 0xc1, 0x69, 0xe2, 0xe3, 0x8f, 0x29, 0x11, 0x2e, 0x64, 0xc9, 0xfc, 0x31, + 0xb2, 0x24, 0x1c, 0x95, 0x25, 0x9f, 0x6a, 0x6c, 0x4a, 0xa9, 0x76, 0xa0, 0xc1, 0x4c, 0xec, 0x1e, + 0xc7, 0x8f, 0xfe, 0x9b, 0x23, 0xbd, 0xe0, 0x67, 0x1a, 0xe4, 0xc3, 0x6b, 0x42, 0x68, 0x15, 0x32, + 0x98, 0x5d, 0x35, 0x61, 0x69, 0x67, 0x36, 0x76, 0x0d, 0x90, 0xe0, 0xf8, 0xc5, 0xbf, 0xd8, 0xed, + 0x92, 0x06, 0x67, 0x7c, 0x8c, 0xaa, 0xfd, 0x8f, 0x5a, 0x50, 0xb5, 0x8f, 0xac, 0x22, 0xf9, 0xc3, + 0x57, 0x71, 0x72, 0xa6, 0xfb, 0x1e, 0x20, 0x4d, 0xd7, 0x42, 0xba, 0x6f, 0x0f, 0x3b, 0x3d, 0xd3, + 0xd2, 0xbb, 0x34, 0x14, 0x73, 0x6c, 0x57, 0x07, 0x30, 0x71, 0x57, 0x07, 0x30, 0xb4, 0x0b, 0x33, + 0xd1, 0x4c, 0x8f, 0x8a, 0x51, 0xdf, 0x3b, 0x7c, 0x5f, 0x26, 0x62, 0xe7, 0x15, 0x31, 0x4e, 0xf9, + 0xe2, 0x40, 0x0c, 0x89, 0x0c, 0x28, 0xb6, 0x6d, 0xcb, 0xd3, 0x4d, 0x0b, 0x3b, 0x4c, 0x51, 0x52, + 0x75, 0xef, 0xea, 0xaa, 0x44, 0xc3, 0x26, 0x2d, 0x32, 0x9f, 0x7c, 0xef, 0x4a, 0xc6, 0xa1, 0x8f, + 0x60, 0x3a, 0xe8, 0x9e, 0x98, 0x92, 0x94, 0xea, 0xde, 0xd5, 0x9a, 0x48, 0xc2, 0x36, 0x83, 0xc4, + 0x25, 0xdf, 0xbb, 0x92, 0x50, 0xe8, 0x43, 0x98, 0xea, 0x92, 0xb6, 0x6e, 0xed, 0xa0, 0x6f, 0x3a, + 0xd8, 0x50, 0xdf, 0x04, 0xbc, 0x2d, 0x50, 0xb0, 0xc4, 0x25, 0xf2, 0xc8, 0x17, 0x20, 0x44, 0x0c, + 0xf1, 0x47, 0x4f, 0x3f, 0x68, 0xf8, 0x96, 0xbb, 0x76, 0xc0, 0x6f, 0x75, 0x65, 0x55, 0xfe, 0xd8, + 0x90, 0x89, 0x98, 0x3f, 0x62, 0x9c, 0xb2, 0x3f, 0x62, 0x48, 0x74, 0x9b, 0xe6, 0x65, 0x66, 0x24, + 0x76, 0x23, 0x70, 0x61, 0xa4, 0xa0, 0x62, 0xf6, 0x61, 0x33, 0x1c, 0xfe, 0x24, 0x09, 0x0d, 0x25, + 0xa0, 0x2e, 0x94, 0xfa, 0xb6, 0x41, 0x5f, 0xbb, 0x81, 0x3d, 0xdf, 0xb1, 0xb0, 0xc1, 0xbb, 0xab, + 0xa5, 0x11, 0xa9, 0x12, 0x15, 0xfb, 0x7c, 0xc5, 0x79, 0xe5, 0xfb, 0x9d, 0x71, 0x2c, 0xfa, 0x14, + 0xe6, 0x62, 0xf7, 0x9b, 0xd8, 0x7b, 0x14, 0x54, 0xe7, 0x1a, 0xeb, 0x0a, 0x4a, 0xd6, 0x08, 0xab, + 0x64, 0x48, 0x9a, 0x95, 0x5a, 0x88, 0xf6, 0x8e, 0x6e, 0x75, 0xd6, 0xed, 0xd6, 0xb6, 0xc5, 0x3b, + 0x47, 0xbd, 0xd5, 0xc5, 0xfc, 0x8a, 0x5f, 0x4c, 0xfb, 0x0d, 0x05, 0x25, 0xd3, 0xae, 0x92, 0x21, + 0x6b, 0x57, 0x51, 0x84, 0x77, 0x99, 0x48, 0x59, 0x11, 0xde, 0xf9, 0x53, 0xdd, 0x65, 0x62, 0x04, + 0xc2, 0x5d, 0x26, 0x06, 0x50, 0xdc, 0x65, 0x62, 0x08, 0x76, 0x0d, 0xae, 0x6d, 0x5b, 0x6d, 0xb3, + 0x6b, 0xd2, 0xb9, 0x38, 0x33, 0x6a, 0x51, 0x7d, 0x0d, 0x6e, 0x84, 0x30, 0xb8, 0x06, 0x37, 0x82, + 0x88, 0x5f, 0x83, 0x1b, 0x21, 0x40, 0x37, 0xa1, 0xb4, 0xa3, 0x9b, 0x5d, 0xdf, 0xc1, 0xcd, 0xb6, + 0xee, 0xe1, 0x8e, 0xed, 0x1c, 0xf2, 0xd3, 0x42, 0x1a, 0xd7, 0x1c, 0x77, 0x95, 0xa3, 0xc4, 0x73, + 0xd1, 0x18, 0x0a, 0xdd, 0x83, 0xd9, 0x40, 0x92, 0xeb, 0xb7, 0x42, 0x61, 0xa7, 0xa9, 0x30, 0x7a, + 0x79, 0x99, 0xa3, 0xb7, 0x22, 0xac, 0x20, 0x0f, 0x8d, 0x62, 0xeb, 0xb9, 0x60, 0x2a, 0xb6, 0x9e, + 0xca, 0xa5, 0x4b, 0x99, 0xf5, 0x54, 0x0e, 0x4a, 0x05, 0x7e, 0x18, 0x79, 0x0f, 0x66, 0x62, 0x99, + 0x11, 0xbd, 0x0b, 0xe1, 0x55, 0xa2, 0xfb, 0x87, 0xfd, 0xa0, 0xec, 0x96, 0xae, 0x1e, 0x11, 0xb8, + 0xea, 0xea, 0x11, 0x81, 0x57, 0xbf, 0x4c, 0x41, 0x2e, 0xd8, 0x7a, 0x27, 0xd2, 0x48, 0xad, 0x40, + 0xb6, 0x87, 0x5d, 0x7a, 0x5d, 0x28, 0x11, 0xd5, 0x63, 0x1c, 0x24, 0xd6, 0x63, 0x1c, 0x24, 0x97, + 0x8b, 0xc9, 0xc7, 0x2a, 0x17, 0x53, 0x13, 0x97, 0x8b, 0x98, 0x9e, 0x90, 0x0b, 0x29, 0x3d, 0x38, + 0x58, 0x7a, 0xf4, 0x77, 0x22, 0x38, 0x3f, 0x17, 0x19, 0x63, 0xe7, 0xe7, 0x22, 0x0a, 0xed, 0xc1, + 0x69, 0xe1, 0xf0, 0x8b, 0x4f, 0x3d, 0x49, 0x2a, 0x2f, 0x8e, 0xbf, 0x8e, 0xd0, 0xa0, 0x54, 0x2c, + 0x61, 0xed, 0xc5, 0xa0, 0x62, 0xbd, 0x1d, 0xc7, 0x91, 0x90, 0x30, 0x70, 0xcb, 0xef, 0x6c, 0x70, + 0xb3, 0x67, 0xa3, 0x90, 0x10, 0xe1, 0x62, 0x48, 0x88, 0xf0, 0xea, 0x3f, 0x13, 0x50, 0x94, 0xdf, + 0xf7, 0x44, 0x02, 0xe3, 0x75, 0xc8, 0xe3, 0x03, 0xd3, 0x6b, 0xb6, 0x6d, 0x03, 0xf3, 0xa6, 0x93, + 0xfa, 0x99, 0x00, 0xaf, 0xda, 0x86, 0xe4, 0xe7, 0x00, 0x26, 0x46, 0x53, 0x72, 0xa2, 0x68, 0x8a, + 0x86, 0xcc, 0xa9, 0x09, 0x86, 0xcc, 0x4a, 0x3f, 0xe5, 0x4f, 0xc6, 0x4f, 0xd5, 0xaf, 0x13, 0x50, + 0x8a, 0x7f, 0x9f, 0x9e, 0x8d, 0x2d, 0x28, 0xef, 0xa6, 0xe4, 0xc4, 0xbb, 0xe9, 0x3d, 0x98, 0x26, + 0x45, 0xa5, 0xee, 0x79, 0xfc, 0x76, 0x71, 0x8a, 0xd6, 0x85, 0x2c, 0x1b, 0xf9, 0xd6, 0x6a, 0x00, + 0x97, 0xb2, 0x91, 0x00, 0x1f, 0x09, 0xdd, 0xf4, 0x31, 0x43, 0xf7, 0xf3, 0x04, 0x4c, 0x6f, 0xda, + 0xc6, 0x7d, 0x56, 0x6f, 0x7a, 0xcf, 0x8a, 0x3d, 0x9f, 0x66, 0x4a, 0xab, 0xce, 0xc0, 0xb4, 0x54, + 0x70, 0x56, 0xbf, 0x60, 0x71, 0x26, 0x7f, 0xd7, 0x7f, 0x7a, 0x76, 0x29, 0xc2, 0x94, 0x58, 0x27, + 0x57, 0xeb, 0x30, 0x13, 0x2b, 0x6b, 0xc5, 0x17, 0xd0, 0x26, 0x79, 0x81, 0xea, 0x35, 0x98, 0x53, + 0xd5, 0x7b, 0x42, 0xd6, 0xd1, 0x26, 0x38, 0x19, 0xbb, 0x01, 0x73, 0xaa, 0xba, 0xed, 0xf8, 0xcb, + 0x79, 0x97, 0x9f, 0x3a, 0xf3, 0x0a, 0xeb, 0xd8, 0xfc, 0xd7, 0x61, 0x56, 0x51, 0x69, 0x1d, 0x5f, + 0xce, 0x37, 0xe1, 0x00, 0x21, 0xfa, 0x45, 0xc0, 0x75, 0x28, 0xf5, 0x83, 0x87, 0x26, 0x6f, 0x53, + 0xd3, 0xd1, 0x15, 0xad, 0x10, 0xb7, 0x1e, 0xeb, 0x57, 0x8b, 0x32, 0x46, 0x96, 0xc3, 0x5b, 0xd8, + 0x8c, 0x42, 0x4e, 0x23, 0xd6, 0xcb, 0x16, 0x65, 0x8c, 0xe0, 0xa2, 0xec, 0xd1, 0x2e, 0xa2, 0x2d, + 0x70, 0xba, 0xfa, 0x99, 0x06, 0x33, 0xb1, 0x5f, 0x2c, 0xa0, 0xcb, 0x90, 0xa3, 0x3f, 0x27, 0x8c, + 0x9a, 0x7f, 0x6a, 0x1d, 0x0a, 0x93, 0x16, 0x90, 0xe5, 0x20, 0xf4, 0x06, 0xe4, 0xc3, 0x1f, 0x31, + 0xf0, 0x73, 0x6b, 0x16, 0xbf, 0x01, 0x50, 0x8a, 0xdf, 0x00, 0xc8, 0xe7, 0x06, 0xff, 0x0f, 0x67, + 0xc7, 0xfe, 0x7c, 0xe1, 0x58, 0x67, 0xa4, 0xd1, 0x00, 0x20, 0x75, 0xac, 0x01, 0xc0, 0x01, 0x2c, + 0xa8, 0x7f, 0x55, 0x20, 0x68, 0x4f, 0x1c, 0xa9, 0x3d, 0xb2, 0x7e, 0x72, 0x42, 0xeb, 0x27, 0xaa, + 0x7b, 0x74, 0x62, 0x12, 0xde, 0xde, 0x47, 0x97, 0x20, 0xdd, 0xb7, 0xed, 0xae, 0xcb, 0x2f, 0x86, + 0x50, 0x75, 0x14, 0x20, 0xaa, 0xa3, 0x80, 0xc7, 0x98, 0xcf, 0xf8, 0x41, 0x04, 0x47, 0xbf, 0x45, + 0x78, 0x0a, 0xd6, 0x7d, 0xf9, 0x32, 0xe4, 0x82, 0xc3, 0x77, 0x04, 0x90, 0xb9, 0xb7, 0xbd, 0xb6, + 0xbd, 0x76, 0xad, 0x74, 0x0a, 0x15, 0x20, 0xbb, 0xb9, 0x76, 0xe7, 0xda, 0xad, 0x3b, 0x37, 0x4a, + 0x1a, 0x79, 0x68, 0x6c, 0xdf, 0xb9, 0x43, 0x1e, 0x12, 0x2f, 0xdf, 0x16, 0x2f, 0xf4, 0xf1, 0x0a, + 0x70, 0x0a, 0x72, 0xab, 0xfd, 0x3e, 0xdd, 0xbc, 0x8c, 0x77, 0x6d, 0xdf, 0x24, 0x19, 0xa1, 0xa4, + 0xa1, 0x2c, 0x24, 0xef, 0xde, 0xdd, 0x28, 0x25, 0xd0, 0x1c, 0x94, 0xae, 0x61, 0xdd, 0xe8, 0x9a, + 0x16, 0x0e, 0xf2, 0x5f, 0x29, 0x59, 0x7f, 0xf8, 0xe7, 0x6f, 0x97, 0xb4, 0xaf, 0xbf, 0x5d, 0xd2, + 0xfe, 0xf1, 0xed, 0x92, 0xf6, 0xe5, 0x77, 0x4b, 0xa7, 0xbe, 0xfe, 0x6e, 0xe9, 0xd4, 0xdf, 0xbe, + 0x5b, 0x3a, 0xf5, 0x7f, 0x97, 0x3b, 0xa6, 0xb7, 0xeb, 0xb7, 0x6a, 0x6d, 0xbb, 0xc7, 0x7f, 0x17, + 0xdd, 0x77, 0x6c, 0x92, 0x68, 0xf8, 0xd3, 0x4a, 0xfc, 0x07, 0xd3, 0xbf, 0x4f, 0x9c, 0x5b, 0xa5, + 0x8f, 0x9b, 0x8c, 0xae, 0x76, 0xcb, 0xae, 0x31, 0x00, 0xfd, 0x89, 0xac, 0xdb, 0xca, 0xd0, 0x9f, + 0xc2, 0xbe, 0xfe, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x54, 0x07, 0xc0, 0x86, 0x6b, 0x3d, 0x00, + 0x00, } func (m *EventSequence) Marshal() (dAtA []byte, err error) { @@ -5578,6 +5592,11 @@ func (m *JobRunLeased) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.RunIndex != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.RunIndex)) + i-- + dAtA[i] = 0x68 + } if len(m.Pool) > 0 { i -= len(m.Pool) copy(dAtA[i:], m.Pool) @@ -8028,6 +8047,9 @@ func (m *JobRunLeased) Size() (n int) { if l > 0 { n += 1 + l + sovEvents(uint64(l)) } + if m.RunIndex != 0 { + n += 1 + sovEvents(uint64(m.RunIndex)) + } return n } @@ -13050,6 +13072,25 @@ func (m *JobRunLeased) Unmarshal(dAtA []byte) error { } m.Pool = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RunIndex", wireType) + } + m.RunIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RunIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) diff --git a/pkg/armadaevents/events.proto b/pkg/armadaevents/events.proto index db0096c6489..11ffaea1cdf 100644 --- a/pkg/armadaevents/events.proto +++ b/pkg/armadaevents/events.proto @@ -312,6 +312,11 @@ message JobRunLeased { // pool is the pool this run was scheduled on to // This would be determined by the pool of the node this run was scheduled on to, at the time of scheduling string pool = 12; + // run_index is the zero-based attempt counter for this run within the job. + // Always 0 for the first attempt. Incremented by the scheduler when retrying + // a failed run under a retry policy. Carried in the event so the + // scheduler-ingester can persist it on the runs row. + uint32 run_index = 13; } // Indicates that a job has been assigned to nodes by Kubernetes. diff --git a/pkg/executorapi/executorapi.pb.go b/pkg/executorapi/executorapi.pb.go index f4794a87256..4f2a1175a8b 100644 --- a/pkg/executorapi/executorapi.pb.go +++ b/pkg/executorapi/executorapi.pb.go @@ -434,6 +434,12 @@ type JobRunLease struct { Groups []string `protobuf:"bytes,5,rep,name=groups,proto3" json:"groups,omitempty"` Job *armadaevents.SubmitJob `protobuf:"bytes,6,opt,name=job,proto3" json:"job,omitempty"` JobRunId string `protobuf:"bytes,7,opt,name=job_run_id,json=jobRunId,proto3" json:"jobRunId,omitempty"` + // job_run_index is the zero-based attempt counter for this run within its job. + // Wrapped to give explicit presence: nil means the scheduler did not populate + // the field (legacy scheduler or feature flag off), so the executor must use + // the legacy pod-name format. Non-nil means the executor must include the + // index as a suffix in the pod name to disambiguate retry attempts. + JobRunIndex *types.UInt32Value `protobuf:"bytes,8,opt,name=job_run_index,json=jobRunIndex,proto3" json:"jobRunIndex,omitempty"` } func (m *JobRunLease) Reset() { *m = JobRunLease{} } @@ -511,6 +517,13 @@ func (m *JobRunLease) GetJobRunId() string { return "" } +func (m *JobRunLease) GetJobRunIndex() *types.UInt32Value { + if m != nil { + return m.JobRunIndex + } + return nil +} + // Indicates that the job runs with the given ids should be cancelled. type CancelRuns struct { JobRunIdsToCancel []string `protobuf:"bytes,2,rep,name=job_run_ids_to_cancel,json=jobRunIdsToCancel,proto3" json:"jobRunIdsToCancel,omitempty"` @@ -775,103 +788,105 @@ func init() { func init() { proto.RegisterFile("pkg/executorapi/executorapi.proto", fileDescriptor_57e0d9d0e484e459) } var fileDescriptor_57e0d9d0e484e459 = []byte{ - // 1526 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x3b, 0x6f, 0xdc, 0xc6, - 0x16, 0x16, 0x57, 0xd2, 0x5a, 0x3b, 0xab, 0xe7, 0xe8, 0x45, 0x49, 0xf6, 0x52, 0xde, 0x8b, 0x7b, - 0x21, 0xe1, 0xda, 0xdc, 0x6b, 0xd9, 0xb8, 0x70, 0x82, 0x24, 0x88, 0xd6, 0x10, 0x1c, 0x09, 0xb6, - 0x63, 0x4b, 0x8a, 0x91, 0xa4, 0x21, 0x86, 0xcb, 0xf1, 0x9a, 0x12, 0x39, 0x43, 0x93, 0x43, 0xc5, - 0xeb, 0x2a, 0x65, 0x8a, 0x14, 0x2e, 0xd2, 0xa4, 0x30, 0xd2, 0xa5, 0xce, 0xcf, 0x48, 0x69, 0x20, - 0x4d, 0x2a, 0x26, 0xb0, 0x3a, 0xf6, 0xe9, 0x83, 0x99, 0x21, 0xb5, 0xc3, 0x7d, 0x58, 0x4e, 0x2a, - 0x21, 0x95, 0x34, 0xe7, 0xf5, 0x7d, 0x73, 0xce, 0x9c, 0xb3, 0x67, 0x17, 0x5c, 0x0d, 0x8e, 0xdb, - 0x0d, 0xfc, 0x1c, 0xb7, 0x62, 0x46, 0x43, 0x14, 0xb8, 0xea, 0xff, 0x66, 0x10, 0x52, 0x46, 0x61, - 0x55, 0x11, 0xad, 0x5e, 0xe1, 0xf6, 0x28, 0xf4, 0x91, 0x83, 0xf0, 0x09, 0x26, 0x2c, 0x6a, 0xc8, - 0x3f, 0xd2, 0x76, 0x75, 0x41, 0xa8, 0x03, 0xb7, 0x11, 0xc5, 0xb6, 0xef, 0xb2, 0x4c, 0xba, 0xd6, - 0xa6, 0xb4, 0xed, 0xe1, 0x86, 0x38, 0xd9, 0xf1, 0x93, 0x06, 0xf6, 0x03, 0xd6, 0xc9, 0x94, 0xf5, - 0xe3, 0xdb, 0x91, 0xe9, 0x52, 0xe1, 0xd5, 0xa2, 0x21, 0x6e, 0x9c, 0xdc, 0x68, 0xb4, 0x31, 0xc1, - 0x21, 0x62, 0xd8, 0xc9, 0x6c, 0x6e, 0x75, 0x6d, 0x7c, 0xd4, 0x7a, 0xea, 0x12, 0x1c, 0x76, 0x1a, - 0x39, 0x54, 0x88, 0x23, 0x1a, 0x87, 0x2d, 0xdc, 0xeb, 0x55, 0xff, 0x63, 0x06, 0x4c, 0x3c, 0xa0, - 0x0e, 0xde, 0x25, 0x4f, 0x28, 0xfc, 0x0f, 0x18, 0x23, 0xc8, 0xc7, 0xba, 0xb6, 0xae, 0x6d, 0x54, - 0x9a, 0x30, 0x4d, 0x8c, 0x69, 0x7e, 0xbe, 0x46, 0x7d, 0x97, 0x09, 0x3a, 0xfb, 0x42, 0x0f, 0xef, - 0x82, 0x32, 0x43, 0x2e, 0x61, 0x91, 0x5e, 0x5a, 0x1f, 0xdd, 0xa8, 0x6e, 0xad, 0x98, 0x12, 0xdb, - 0xe4, 0x09, 0xe1, 0xfc, 0xcc, 0x93, 0x1b, 0xe6, 0x21, 0xb7, 0x68, 0x2e, 0xa4, 0x89, 0x31, 0x2b, - 0x8d, 0x95, 0x30, 0x99, 0x3b, 0xfc, 0x14, 0x94, 0x3d, 0x64, 0x63, 0x2f, 0xd2, 0x47, 0x45, 0xa0, - 0xab, 0xa6, 0x9a, 0xda, 0x9c, 0x97, 0x79, 0x4f, 0xd8, 0xec, 0x10, 0x16, 0x76, 0x64, 0x40, 0xe9, - 0xa4, 0x06, 0x94, 0x12, 0xf8, 0x8d, 0x06, 0x16, 0x91, 0xe7, 0xd1, 0x16, 0x62, 0xc8, 0xf6, 0xb0, - 0x95, 0xdf, 0x3b, 0xd2, 0xc7, 0x04, 0x40, 0x63, 0x30, 0xc0, 0x76, 0xd7, 0x65, 0x3f, 0xf7, 0x90, - 0x70, 0xf5, 0x34, 0x31, 0x6a, 0x68, 0x80, 0x5a, 0x01, 0x5f, 0x18, 0xa4, 0x87, 0x5f, 0x6b, 0x60, - 0x1e, 0x9d, 0x20, 0xd7, 0xeb, 0x21, 0x32, 0x2e, 0x88, 0x5c, 0x1f, 0x42, 0x24, 0x77, 0xe8, 0xa1, - 0xb1, 0x9e, 0x26, 0xc6, 0x65, 0xd4, 0xa7, 0x54, 0x48, 0xc0, 0x7e, 0x2d, 0x0c, 0xc0, 0x0c, 0xa3, - 0x0c, 0x79, 0x0a, 0x7a, 0x59, 0xa0, 0x6f, 0x0e, 0x46, 0x3f, 0xe4, 0xc6, 0x3d, 0xc8, 0x97, 0xd3, - 0xc4, 0xd0, 0x59, 0x41, 0xa1, 0xa0, 0x4e, 0x17, 0x35, 0x90, 0x80, 0xd9, 0x30, 0x26, 0x96, 0xeb, - 0x44, 0x96, 0xdd, 0xb1, 0x22, 0x86, 0x18, 0xd6, 0x27, 0x04, 0xe4, 0xc6, 0x60, 0xc8, 0xfd, 0x98, - 0xec, 0x3a, 0x51, 0xb3, 0x73, 0xc0, 0x4d, 0x25, 0xe2, 0x5a, 0x9a, 0x18, 0xcb, 0xa1, 0x2a, 0x57, - 0x00, 0xa7, 0x0a, 0x0a, 0xf8, 0xa3, 0x06, 0x6a, 0x84, 0x12, 0x4b, 0x76, 0x9b, 0x95, 0x15, 0x02, - 0x3b, 0xca, 0x8d, 0x2b, 0x02, 0xfe, 0xff, 0x83, 0xe1, 0x1f, 0x50, 0xb2, 0x2d, 0x5c, 0xb7, 0x73, - 0xcf, 0x9e, 0xeb, 0x6f, 0xa6, 0x89, 0xf1, 0x6f, 0x32, 0xdc, 0x4a, 0xa1, 0xb6, 0xf6, 0x16, 0x33, - 0xb8, 0x0d, 0xa6, 0x62, 0x12, 0xb5, 0x9e, 0x62, 0x27, 0x16, 0x45, 0xd2, 0xc1, 0xba, 0xb6, 0x31, - 0x21, 0xef, 0x5a, 0x50, 0xa8, 0x77, 0x2d, 0x28, 0xe0, 0x4d, 0x50, 0x21, 0xd4, 0xc1, 0x16, 0xeb, - 0x04, 0x58, 0x9f, 0x14, 0x2d, 0xba, 0x94, 0x26, 0x06, 0xe4, 0xc2, 0xc3, 0x4e, 0xa0, 0x7a, 0x4e, - 0xe4, 0x32, 0xde, 0xd2, 0x01, 0xa5, 0x9e, 0x3e, 0xd5, 0x6d, 0x69, 0x7e, 0x56, 0x5b, 0x9a, 0x9f, - 0xe1, 0x4b, 0x0d, 0xac, 0xe7, 0x39, 0xb3, 0xe2, 0x08, 0xb5, 0x31, 0x2f, 0xe0, 0xb3, 0x18, 0xc7, - 0xd8, 0x42, 0xc4, 0xb1, 0x44, 0x90, 0x69, 0x91, 0xca, 0x5a, 0x21, 0x95, 0x0f, 0x29, 0xf5, 0x1e, - 0x71, 0xb3, 0xfc, 0xae, 0x32, 0x65, 0x79, 0xac, 0xcf, 0x78, 0xa8, 0x66, 0x47, 0x58, 0x6c, 0x13, - 0xe7, 0x61, 0x11, 0x7b, 0xed, 0x2d, 0x66, 0xab, 0x08, 0x54, 0x95, 0xc6, 0x87, 0xff, 0x02, 0xa3, - 0xc7, 0xb8, 0x93, 0xcd, 0xa6, 0xb9, 0x34, 0x31, 0xa6, 0x8e, 0x71, 0x47, 0x89, 0xc5, 0xb5, 0x70, - 0x13, 0x8c, 0x9f, 0x20, 0x2f, 0xc6, 0x7a, 0x49, 0x98, 0xcd, 0xa7, 0x89, 0x31, 0x23, 0x04, 0x8a, - 0xa1, 0xb4, 0x78, 0xbf, 0x74, 0x5b, 0x5b, 0xfd, 0x41, 0x03, 0x2b, 0x43, 0x7b, 0xff, 0xdd, 0x10, - 0xbf, 0x50, 0x11, 0xab, 0x5b, 0xa6, 0x32, 0x0a, 0xcf, 0xc6, 0xb0, 0x19, 0x1c, 0xb7, 0xc5, 0x6c, - 0xcc, 0xaf, 0x6b, 0x3e, 0x8a, 0x11, 0x61, 0x2e, 0xeb, 0x9c, 0xcb, 0xf0, 0x95, 0x06, 0x96, 0x87, - 0x0c, 0x85, 0x0b, 0xc1, 0xef, 0x7b, 0x0d, 0xcc, 0x0f, 0x18, 0x1b, 0x17, 0x82, 0xdb, 0x57, 0x00, - 0xf6, 0x8f, 0x97, 0x77, 0x63, 0x76, 0x5b, 0x65, 0x36, 0xbd, 0x35, 0x25, 0x18, 0xec, 0x51, 0x5b, - 0xc4, 0x39, 0x17, 0xf8, 0x3b, 0x0d, 0xac, 0x9f, 0x37, 0x59, 0x54, 0x1e, 0xe3, 0x43, 0x79, 0xdc, - 0x2d, 0x66, 0xe8, 0x72, 0xa1, 0xf5, 0xee, 0x50, 0x3f, 0x88, 0x59, 0xb7, 0xf1, 0xce, 0xa1, 0xb5, - 0x37, 0x36, 0x71, 0x69, 0x76, 0x62, 0x6f, 0x6c, 0xa2, 0x3a, 0x3b, 0x59, 0xff, 0xb6, 0x04, 0x66, - 0x7a, 0xfc, 0xa1, 0x0d, 0x2a, 0xdd, 0xb1, 0xa9, 0x89, 0x5e, 0xff, 0xef, 0xdb, 0x00, 0xcd, 0x9e, - 0x59, 0xb9, 0x9c, 0x26, 0xc6, 0x7c, 0x38, 0x60, 0x32, 0x76, 0xc3, 0xf2, 0xd4, 0x4c, 0x5f, 0xbc, - 0xa7, 0x52, 0x3f, 0x2d, 0x81, 0xb9, 0xbe, 0x49, 0x76, 0x36, 0x3c, 0xb5, 0x73, 0x86, 0xe7, 0x26, - 0x18, 0x17, 0x93, 0x52, 0x9d, 0x3a, 0x42, 0xa0, 0x82, 0x09, 0x01, 0x74, 0xd4, 0x1c, 0x8f, 0x0e, - 0x58, 0x05, 0xfa, 0x58, 0xfc, 0x83, 0xb2, 0xfc, 0x18, 0x54, 0x76, 0xf8, 0x26, 0x7c, 0xcf, 0x8d, - 0x18, 0xdc, 0x05, 0x65, 0xb9, 0x16, 0x67, 0x4f, 0x6d, 0xcd, 0x54, 0x57, 0x66, 0x53, 0x18, 0x1e, - 0xe0, 0x67, 0x31, 0x26, 0x2d, 0x2c, 0xb7, 0x3e, 0xa9, 0x51, 0xb7, 0x3e, 0x29, 0xa9, 0xff, 0x56, - 0x06, 0x93, 0xf7, 0x30, 0x8a, 0xf0, 0x3e, 0xb7, 0x8f, 0x18, 0x7c, 0x0f, 0x9c, 0x2d, 0xe4, 0x96, - 0xeb, 0x64, 0x97, 0xd6, 0xd3, 0xc4, 0x58, 0xc8, 0xc5, 0xbb, 0x8e, 0x12, 0x07, 0x74, 0xa5, 0x67, - 0x35, 0x2f, 0x9d, 0x53, 0x73, 0xab, 0xbf, 0x90, 0xc5, 0x15, 0x47, 0x25, 0xf4, 0x37, 0x6a, 0x08, - 0x63, 0x30, 0xeb, 0xbb, 0xc4, 0xf5, 0x63, 0xdf, 0x3a, 0xa2, 0xb6, 0x15, 0xb9, 0x2f, 0x70, 0xb6, - 0xc4, 0x5e, 0x1f, 0x8e, 0x73, 0x5f, 0x7a, 0xf0, 0x49, 0xe5, 0xbe, 0xc0, 0xca, 0x06, 0xe7, 0x17, - 0x14, 0xea, 0x06, 0x57, 0xd4, 0xc0, 0x8f, 0xc1, 0x38, 0x5f, 0x1e, 0xf2, 0x3d, 0x75, 0x71, 0xe0, - 0xde, 0x24, 0x2b, 0x2d, 0xec, 0xd4, 0x4a, 0x0b, 0x01, 0xbc, 0x0b, 0xe6, 0x7c, 0xf4, 0x9c, 0x93, - 0x8e, 0x2c, 0x46, 0x2d, 0x8f, 0xf3, 0xd3, 0x2f, 0xad, 0x6b, 0x1b, 0x53, 0x19, 0x15, 0xf4, 0x7c, - 0x8f, 0xda, 0xd1, 0x21, 0x15, 0xcc, 0x0b, 0x54, 0x0a, 0x1a, 0xf8, 0x18, 0x2c, 0xc5, 0x04, 0x45, - 0x91, 0xdb, 0x26, 0xd8, 0x11, 0x49, 0xc8, 0x76, 0x4b, 0xb1, 0x52, 0x56, 0x9a, 0x57, 0xd3, 0xc4, - 0xb8, 0xd2, 0xb5, 0xd8, 0xa3, 0xb6, 0x1c, 0xf7, 0x4a, 0xc8, 0xf9, 0x01, 0xea, 0x0b, 0xda, 0x1d, - 0xe2, 0xa3, 0x74, 0x40, 0xfd, 0x2e, 0x44, 0xe7, 0xfe, 0x54, 0x02, 0x55, 0x99, 0x40, 0x59, 0x9a, - 0xbf, 0x30, 0xf1, 0xae, 0x81, 0x32, 0x7f, 0x0a, 0x98, 0xe9, 0xa3, 0xc2, 0x56, 0xb4, 0xb2, 0x94, - 0xa8, 0xad, 0x2c, 0x25, 0xbc, 0xfd, 0xe2, 0x08, 0x87, 0xfa, 0x58, 0xb7, 0xfd, 0xf8, 0x59, 0x6d, - 0x3f, 0x7e, 0xe6, 0x51, 0xdb, 0x21, 0x8d, 0x03, 0xf9, 0x4e, 0xb3, 0xa8, 0x52, 0xa2, 0x46, 0x95, - 0x12, 0xf8, 0x01, 0x18, 0x3d, 0xa2, 0xb6, 0x5e, 0x16, 0xb9, 0x59, 0x2e, 0x0e, 0x9a, 0x03, 0xf1, - 0x2d, 0x7c, 0x8f, 0xda, 0x32, 0xb7, 0x47, 0xd4, 0x56, 0x73, 0x7b, 0x44, 0x6d, 0x78, 0x0b, 0x80, - 0xee, 0xe3, 0x13, 0x2f, 0x39, 0xdb, 0xbc, 0x8f, 0xb2, 0x27, 0xa5, 0x6e, 0xde, 0xb9, 0xac, 0x6e, - 0x01, 0x70, 0x07, 0x91, 0x16, 0xf6, 0xf6, 0x63, 0x12, 0xc1, 0x47, 0x60, 0x51, 0x79, 0xc0, 0xbc, - 0x2f, 0x5a, 0x42, 0x29, 0xbe, 0x41, 0x57, 0x9a, 0x46, 0x9a, 0x18, 0x6b, 0xb9, 0x6b, 0x74, 0x48, - 0xa5, 0xa7, 0x12, 0x77, 0xae, 0x4f, 0x59, 0x6f, 0x81, 0xea, 0xc3, 0x10, 0x73, 0xb5, 0x40, 0x38, - 0x04, 0x4b, 0x3d, 0x08, 0x81, 0xd4, 0x66, 0x10, 0xe2, 0x2b, 0xa4, 0x12, 0x25, 0xf3, 0x55, 0xbf, - 0x42, 0xf6, 0x6b, 0xeb, 0x55, 0x50, 0xd9, 0x21, 0xce, 0x7d, 0x14, 0x1e, 0xe3, 0xb0, 0xfe, 0x4b, - 0x09, 0x40, 0x51, 0xff, 0x03, 0x16, 0x62, 0xe4, 0xdf, 0xc7, 0x11, 0x5f, 0xdb, 0xe1, 0x0e, 0x18, - 0x97, 0x4d, 0xae, 0x89, 0xfc, 0xea, 0x85, 0x91, 0xa1, 0xbc, 0x1a, 0xf9, 0x4c, 0xbc, 0x62, 0xd7, - 0x7f, 0x32, 0xb2, 0x2f, 0xbd, 0xe1, 0x21, 0xa8, 0xca, 0x9c, 0xf0, 0x3b, 0x44, 0xd9, 0x43, 0x5e, - 0x2e, 0x2e, 0x20, 0x67, 0x09, 0x95, 0xd3, 0xbc, 0x75, 0x76, 0x2e, 0x04, 0x04, 0x5d, 0x39, 0xfc, - 0x10, 0x8c, 0x62, 0xe2, 0x88, 0xb7, 0x57, 0xdd, 0x5a, 0x2a, 0x44, 0x3b, 0xbb, 0x98, 0xac, 0x3c, - 0x26, 0x4e, 0x21, 0x0a, 0xf7, 0x83, 0x9f, 0x83, 0xc9, 0x2c, 0x8d, 0x92, 0xd5, 0xd8, 0x80, 0x2b, - 0x2a, 0x55, 0x68, 0xae, 0xa4, 0x89, 0xb1, 0x18, 0x74, 0x05, 0x85, 0x88, 0x55, 0x45, 0xd1, 0xbc, - 0x04, 0xc6, 0xc5, 0x0b, 0xdc, 0x7a, 0xa5, 0x81, 0xea, 0x4e, 0x16, 0x6e, 0x3b, 0x70, 0xe1, 0x83, - 0xec, 0xc3, 0x4c, 0x66, 0x2e, 0x82, 0x2b, 0x43, 0xc7, 0xfd, 0xaa, 0xd1, 0xaf, 0x2a, 0x94, 0x66, - 0x43, 0xfb, 0x9f, 0x06, 0x3f, 0x02, 0x93, 0xfb, 0x38, 0xa0, 0x21, 0x13, 0x1f, 0xa9, 0x11, 0xec, - 0x49, 0x42, 0xfe, 0x81, 0xbc, 0xba, 0x64, 0xca, 0x9f, 0xa0, 0xcc, 0xfc, 0x27, 0x28, 0x73, 0x87, - 0xf3, 0x6e, 0xee, 0xfe, 0xfc, 0xa6, 0xa6, 0xbd, 0x7e, 0x53, 0xd3, 0x7e, 0x7f, 0x53, 0xd3, 0x5e, - 0x9e, 0xd6, 0x46, 0x5e, 0x9f, 0xd6, 0x46, 0x7e, 0x3d, 0xad, 0x8d, 0x7c, 0xd9, 0x68, 0xbb, 0xec, - 0x69, 0x6c, 0x9b, 0x2d, 0xea, 0x67, 0xbf, 0x77, 0x05, 0x21, 0x3d, 0xc2, 0x2d, 0x96, 0x9d, 0x1a, - 0x3d, 0x3f, 0x9c, 0xd9, 0x65, 0x11, 0xfa, 0xe6, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x80, 0x1b, - 0x8b, 0x62, 0x52, 0x13, 0x00, 0x00, + // 1564 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0xbb, 0x6f, 0xdb, 0x46, + 0x18, 0x37, 0x2d, 0x5b, 0x91, 0x4e, 0x7e, 0x9e, 0x5f, 0xb4, 0x9d, 0x88, 0x8e, 0x8a, 0x16, 0x36, + 0x9a, 0x50, 0x8d, 0x13, 0x14, 0x69, 0xd1, 0x16, 0xb5, 0x02, 0x23, 0xb5, 0x91, 0xa4, 0x89, 0xed, + 0x04, 0x7d, 0x0c, 0xc4, 0x51, 0xbc, 0x28, 0xb4, 0xa5, 0x3b, 0x86, 0x3c, 0x3a, 0x56, 0xa6, 0x8e, + 0x1d, 0x5a, 0x20, 0x43, 0x97, 0x0e, 0x41, 0xb7, 0xfe, 0x2d, 0x1d, 0x03, 0x74, 0xe9, 0xc4, 0x16, + 0xf1, 0xc6, 0xbd, 0x7b, 0x71, 0x77, 0xa4, 0x74, 0xd4, 0x23, 0x4e, 0x3b, 0x19, 0x9d, 0xec, 0xfb, + 0x9e, 0xbf, 0xfb, 0x5e, 0xfc, 0x4e, 0xe0, 0xb2, 0x77, 0xd4, 0xa8, 0xe2, 0x13, 0x5c, 0x0f, 0x19, + 0xf5, 0x91, 0xe7, 0xaa, 0xff, 0x9b, 0x9e, 0x4f, 0x19, 0x85, 0x25, 0x85, 0xb4, 0x72, 0x89, 0xcb, + 0x23, 0xbf, 0x85, 0x1c, 0x84, 0x8f, 0x31, 0x61, 0x41, 0x55, 0xfe, 0x91, 0xb2, 0x2b, 0xf3, 0x82, + 0xed, 0xb9, 0xd5, 0x20, 0xb4, 0x5b, 0x2e, 0x4b, 0xa8, 0xab, 0x0d, 0x4a, 0x1b, 0x4d, 0x5c, 0x15, + 0x27, 0x3b, 0x7c, 0x5c, 0xc5, 0x2d, 0x8f, 0xb5, 0x13, 0x66, 0xb9, 0x97, 0xf9, 0xcc, 0x47, 0x9e, + 0x87, 0xfd, 0xd4, 0x64, 0xe5, 0xe8, 0x66, 0x60, 0xba, 0x54, 0x58, 0xad, 0x53, 0x1f, 0x57, 0x8f, + 0xaf, 0x55, 0x1b, 0x98, 0x60, 0x1f, 0x31, 0xec, 0x24, 0x32, 0x37, 0xba, 0x32, 0x2d, 0x54, 0x7f, + 0xe2, 0x12, 0xec, 0xb7, 0xab, 0x29, 0x14, 0x1f, 0x07, 0x34, 0xf4, 0xeb, 0xb8, 0x57, 0xab, 0xf2, + 0xf7, 0x34, 0x28, 0xdc, 0xa3, 0x0e, 0xde, 0x21, 0x8f, 0x29, 0x7c, 0x0f, 0x8c, 0x11, 0xd4, 0xc2, + 0xba, 0xb6, 0xa6, 0xad, 0x17, 0x6b, 0x30, 0x8e, 0x8c, 0x29, 0x7e, 0xbe, 0x42, 0x5b, 0x2e, 0x13, + 0x70, 0xf7, 0x04, 0x1f, 0xde, 0x06, 0x79, 0x86, 0x5c, 0xc2, 0x02, 0x7d, 0x74, 0x2d, 0xb7, 0x5e, + 0xda, 0x5c, 0x36, 0xa5, 0x6f, 0x93, 0x07, 0x8c, 0xe3, 0x33, 0x8f, 0xaf, 0x99, 0x07, 0x5c, 0xa2, + 0x36, 0x1f, 0x47, 0xc6, 0x8c, 0x14, 0x56, 0xcc, 0x24, 0xea, 0xf0, 0x4b, 0x90, 0x6f, 0x22, 0x1b, + 0x37, 0x03, 0x3d, 0x27, 0x0c, 0x5d, 0x36, 0xd5, 0xd0, 0xa7, 0xb8, 0xcc, 0x3b, 0x42, 0x66, 0x9b, + 0x30, 0xbf, 0x2d, 0x0d, 0x4a, 0x25, 0xd5, 0xa0, 0xa4, 0xc0, 0xef, 0x35, 0xb0, 0x80, 0x9a, 0x4d, + 0x5a, 0x47, 0x0c, 0xd9, 0x4d, 0x6c, 0xa5, 0xf7, 0x0e, 0xf4, 0x31, 0xe1, 0xa0, 0x3a, 0xd8, 0xc1, + 0x56, 0x57, 0x65, 0x2f, 0xd5, 0x90, 0xee, 0x2a, 0x71, 0x64, 0x94, 0xd1, 0x00, 0xb6, 0xe2, 0x7c, + 0x7e, 0x10, 0x1f, 0x7e, 0xa7, 0x81, 0x39, 0x74, 0x8c, 0xdc, 0x66, 0x0f, 0x90, 0x71, 0x01, 0xe4, + 0xea, 0x10, 0x20, 0xa9, 0x42, 0x0f, 0x8c, 0xb5, 0x38, 0x32, 0x2e, 0xa2, 0x3e, 0xa6, 0x02, 0x02, + 0xf6, 0x73, 0xa1, 0x07, 0xa6, 0x19, 0x65, 0xa8, 0xa9, 0x78, 0xcf, 0x0b, 0xef, 0x1b, 0x83, 0xbd, + 0x1f, 0x70, 0xe1, 0x1e, 0xcf, 0x17, 0xe3, 0xc8, 0xd0, 0x59, 0x86, 0xa1, 0x78, 0x9d, 0xca, 0x72, + 0x20, 0x01, 0x33, 0x7e, 0x48, 0x2c, 0xd7, 0x09, 0x2c, 0xbb, 0x6d, 0x05, 0x0c, 0x31, 0xac, 0x17, + 0x84, 0xcb, 0xf5, 0xc1, 0x2e, 0xf7, 0x42, 0xb2, 0xe3, 0x04, 0xb5, 0xf6, 0x3e, 0x17, 0x95, 0x1e, + 0x57, 0xe3, 0xc8, 0x58, 0xf2, 0x55, 0xba, 0xe2, 0x70, 0x32, 0xc3, 0x80, 0xbf, 0x6a, 0xa0, 0x4c, + 0x28, 0xb1, 0x64, 0x37, 0x5a, 0x49, 0x22, 0xb0, 0xa3, 0xdc, 0xb8, 0x28, 0xdc, 0x7f, 0x38, 0xd8, + 0xfd, 0x3d, 0x4a, 0xb6, 0x84, 0xea, 0x56, 0xaa, 0xd9, 0x73, 0xfd, 0x8d, 0x38, 0x32, 0xde, 0x25, + 0xc3, 0xa5, 0x14, 0x68, 0xab, 0x6f, 0x10, 0x83, 0x5b, 0x60, 0x32, 0x24, 0x41, 0xfd, 0x09, 0x76, + 0x42, 0x91, 0x24, 0x1d, 0xac, 0x69, 0xeb, 0x05, 0x79, 0xd7, 0x0c, 0x43, 0xbd, 0x6b, 0x86, 0x01, + 0xaf, 0x83, 0x22, 0xa1, 0x0e, 0xb6, 0x58, 0xdb, 0xc3, 0xfa, 0x84, 0x68, 0xd1, 0xc5, 0x38, 0x32, + 0x20, 0x27, 0x1e, 0xb4, 0x3d, 0x55, 0xb3, 0x90, 0xd2, 0x78, 0x4b, 0x7b, 0x94, 0x36, 0xf5, 0xc9, + 0x6e, 0x4b, 0xf3, 0xb3, 0xda, 0xd2, 0xfc, 0x0c, 0x5f, 0x68, 0x60, 0x2d, 0x8d, 0x99, 0x15, 0x06, + 0xa8, 0x81, 0x79, 0x02, 0x9f, 0x86, 0x38, 0xc4, 0x16, 0x22, 0x8e, 0x25, 0x8c, 0x4c, 0x89, 0x50, + 0x96, 0x33, 0xa1, 0xbc, 0x4f, 0x69, 0xf3, 0x01, 0x17, 0x4b, 0xef, 0x2a, 0x43, 0x96, 0xda, 0x7a, + 0xc8, 0x4d, 0xd5, 0xda, 0x42, 0x62, 0x8b, 0x38, 0xf7, 0xb3, 0xbe, 0x57, 0xdf, 0x20, 0xb6, 0x82, + 0x40, 0x49, 0x69, 0x7c, 0xf8, 0x0e, 0xc8, 0x1d, 0xe1, 0x76, 0x32, 0x9b, 0x66, 0xe3, 0xc8, 0x98, + 0x3c, 0xc2, 0x6d, 0xc5, 0x16, 0xe7, 0xc2, 0x0d, 0x30, 0x7e, 0x8c, 0x9a, 0x21, 0xd6, 0x47, 0x85, + 0xd8, 0x5c, 0x1c, 0x19, 0xd3, 0x82, 0xa0, 0x08, 0x4a, 0x89, 0x8f, 0x47, 0x6f, 0x6a, 0x2b, 0xbf, + 0x68, 0x60, 0x79, 0x68, 0xef, 0xbf, 0x9d, 0xc7, 0xaf, 0x55, 0x8f, 0xa5, 0x4d, 0x53, 0x19, 0x85, + 0x9d, 0x31, 0x6c, 0x7a, 0x47, 0x0d, 0x31, 0x1b, 0xd3, 0xeb, 0x9a, 0x0f, 0x42, 0x44, 0x98, 0xcb, + 0xda, 0x67, 0x22, 0x7c, 0xa9, 0x81, 0xa5, 0x21, 0x43, 0xe1, 0x5c, 0xe0, 0xfb, 0x59, 0x03, 0x73, + 0x03, 0xc6, 0xc6, 0xb9, 0xc0, 0xf6, 0x0c, 0xc0, 0xfe, 0xf1, 0xf2, 0x76, 0xc8, 0x6e, 0xaa, 0xc8, + 0xa6, 0x36, 0x27, 0x05, 0x82, 0x5d, 0x6a, 0x0b, 0x3b, 0x67, 0x3a, 0xfe, 0x49, 0x03, 0x6b, 0x67, + 0x4d, 0x16, 0x15, 0xc7, 0xf8, 0x50, 0x1c, 0xb7, 0xb3, 0x11, 0xba, 0x98, 0x69, 0xbd, 0x5b, 0xb4, + 0xe5, 0x85, 0xac, 0xdb, 0x78, 0x67, 0xc0, 0xda, 0x1d, 0x2b, 0x5c, 0x98, 0x29, 0xec, 0x8e, 0x15, + 0x4a, 0x33, 0x13, 0x95, 0x1f, 0x46, 0xc1, 0x74, 0x8f, 0x3e, 0xb4, 0x41, 0xb1, 0x3b, 0x36, 0x35, + 0xd1, 0xeb, 0xef, 0xbf, 0xc9, 0xa1, 0xd9, 0x33, 0x2b, 0x97, 0xe2, 0xc8, 0x98, 0xf3, 0x07, 0x4c, + 0xc6, 0xae, 0x59, 0x1e, 0x9a, 0xa9, 0xf3, 0x57, 0x2a, 0x95, 0xd3, 0x51, 0x30, 0xdb, 0x37, 0xc9, + 0x3a, 0xc3, 0x53, 0x3b, 0x63, 0x78, 0x6e, 0x80, 0x71, 0x31, 0x29, 0xd5, 0xa9, 0x23, 0x08, 0xaa, + 0x33, 0x41, 0x80, 0x8e, 0x1a, 0xe3, 0xdc, 0x80, 0x55, 0xa0, 0x0f, 0xc5, 0xff, 0x28, 0xca, 0x8f, + 0x40, 0x71, 0x9b, 0x6f, 0xca, 0x77, 0xdc, 0x80, 0xc1, 0x1d, 0x90, 0x97, 0x6b, 0x73, 0x52, 0x6a, + 0xab, 0xa6, 0xba, 0x52, 0x9b, 0x42, 0x70, 0x1f, 0x3f, 0x0d, 0x31, 0xa9, 0x63, 0xb9, 0xf5, 0x49, + 0x8e, 0xba, 0xf5, 0x49, 0x4a, 0xe5, 0xcf, 0x3c, 0x98, 0xb8, 0x83, 0x51, 0x80, 0xf7, 0xb8, 0x7c, + 0xc0, 0xe0, 0x47, 0xa0, 0xb3, 0xb0, 0x5b, 0xae, 0x93, 0x5c, 0x5a, 0x8f, 0x23, 0x63, 0x3e, 0x25, + 0xef, 0x38, 0x8a, 0x1d, 0xd0, 0xa5, 0x76, 0x72, 0x3e, 0x7a, 0x46, 0xce, 0xad, 0xfe, 0x44, 0x66, + 0x57, 0x1c, 0x15, 0xd0, 0x7f, 0xc8, 0x21, 0x0c, 0xc1, 0x4c, 0xcb, 0x25, 0x6e, 0x2b, 0x6c, 0x59, + 0x87, 0xd4, 0xb6, 0x02, 0xf7, 0x39, 0x4e, 0x96, 0xd8, 0xab, 0xc3, 0xfd, 0xdc, 0x95, 0x1a, 0x7c, + 0x52, 0xb9, 0xcf, 0xb1, 0xb2, 0xc1, 0xb5, 0x32, 0x0c, 0x75, 0x83, 0xcb, 0x72, 0xe0, 0xe7, 0x60, + 0x9c, 0x2f, 0x0f, 0xe9, 0x9e, 0xba, 0x30, 0x70, 0x6f, 0x92, 0x99, 0x16, 0x72, 0x6a, 0xa6, 0x05, + 0x01, 0xde, 0x06, 0xb3, 0x2d, 0x74, 0xc2, 0x41, 0x07, 0x16, 0xa3, 0x56, 0x93, 0xe3, 0xd3, 0x2f, + 0xac, 0x69, 0xeb, 0x93, 0x09, 0x14, 0x74, 0xb2, 0x4b, 0xed, 0xe0, 0x80, 0x0a, 0xe4, 0x19, 0x28, + 0x19, 0x0e, 0x7c, 0x04, 0x16, 0x43, 0x82, 0x82, 0xc0, 0x6d, 0x10, 0xec, 0x88, 0x20, 0x24, 0xbb, + 0xa5, 0x58, 0x29, 0x8b, 0xb5, 0xcb, 0x71, 0x64, 0x5c, 0xea, 0x4a, 0xec, 0x52, 0x5b, 0x8e, 0x7b, + 0xc5, 0xe4, 0xdc, 0x00, 0xf6, 0x39, 0xed, 0x0e, 0xf1, 0x29, 0x1d, 0x90, 0xbf, 0x73, 0xd1, 0xb9, + 0x3f, 0xe6, 0x40, 0x49, 0x06, 0x50, 0xa6, 0xe6, 0x5f, 0x4c, 0xbc, 0x2b, 0x20, 0xcf, 0x4b, 0x01, + 0x33, 0x3d, 0x27, 0x64, 0x45, 0x2b, 0x4b, 0x8a, 0xda, 0xca, 0x92, 0xc2, 0xdb, 0x2f, 0x0c, 0xb0, + 0xaf, 0x8f, 0x75, 0xdb, 0x8f, 0x9f, 0xd5, 0xf6, 0xe3, 0x67, 0x6e, 0xb5, 0xe1, 0xd3, 0xd0, 0x93, + 0x75, 0x9a, 0x58, 0x95, 0x14, 0xd5, 0xaa, 0xa4, 0xc0, 0x4f, 0x40, 0xee, 0x90, 0xda, 0x7a, 0x5e, + 0xc4, 0x66, 0x29, 0x3b, 0x68, 0xf6, 0xc5, 0x2b, 0x7d, 0x97, 0xda, 0x32, 0xb6, 0x87, 0xd4, 0x56, + 0x63, 0x7b, 0x48, 0x6d, 0x78, 0x03, 0x80, 0x6e, 0xf1, 0x89, 0x4a, 0x4e, 0x36, 0xef, 0xc3, 0xa4, + 0xa4, 0xd4, 0xcd, 0x3b, 0xa5, 0xc1, 0x6f, 0xc1, 0x64, 0x47, 0x8b, 0x38, 0xf8, 0x44, 0x2f, 0x24, + 0x9f, 0x70, 0xf9, 0xd6, 0x37, 0xd3, 0xb7, 0xbe, 0xf9, 0x70, 0x87, 0xb0, 0xeb, 0x9b, 0x8f, 0x78, + 0xac, 0x6b, 0xcb, 0x71, 0x64, 0x2c, 0x24, 0x26, 0xb8, 0x92, 0x62, 0xb9, 0xa4, 0x90, 0x2b, 0x16, + 0x00, 0xb7, 0x10, 0xa9, 0xe3, 0xe6, 0x5e, 0x48, 0x02, 0xf8, 0x00, 0x2c, 0x28, 0xdd, 0xc1, 0x9b, + 0xae, 0x2e, 0x98, 0xe2, 0x79, 0x5e, 0xac, 0x19, 0x71, 0x64, 0xac, 0xa6, 0xb8, 0x82, 0x03, 0x2a, + 0x35, 0x15, 0xd3, 0xb3, 0x7d, 0xcc, 0x4a, 0x1d, 0x94, 0xee, 0xfb, 0x98, 0xb3, 0x85, 0x87, 0x03, + 0xb0, 0xd8, 0xe3, 0xc1, 0x93, 0xdc, 0xc4, 0x85, 0x78, 0x9f, 0x2a, 0x56, 0x12, 0x5d, 0xf5, 0x7d, + 0xda, 0xcf, 0xad, 0x94, 0x40, 0x71, 0x9b, 0x38, 0x77, 0x91, 0x7f, 0x84, 0xfd, 0xca, 0xef, 0xa3, + 0x00, 0x8a, 0xe2, 0xda, 0x67, 0x3e, 0x46, 0xad, 0xbb, 0x38, 0xe0, 0x6f, 0x02, 0xb8, 0x0d, 0xc6, + 0xe5, 0x04, 0xd1, 0x44, 0xf8, 0xf4, 0xcc, 0x3c, 0x52, 0x4a, 0x52, 0xd6, 0x60, 0x33, 0x3b, 0x52, + 0xbe, 0x18, 0xd9, 0x93, 0xda, 0xf0, 0x00, 0x94, 0x64, 0x4c, 0xf8, 0x1d, 0x82, 0xa4, 0x4b, 0x96, + 0xb2, 0xdb, 0x4d, 0x27, 0xa0, 0xf2, 0x53, 0x51, 0xef, 0x9c, 0x33, 0x06, 0x41, 0x97, 0x0e, 0x3f, + 0x05, 0x39, 0x4c, 0x1c, 0x51, 0xd8, 0xa5, 0xcd, 0xc5, 0x8c, 0xb5, 0xce, 0xc5, 0x64, 0x59, 0x61, + 0xe2, 0x64, 0xac, 0x70, 0x3d, 0xf8, 0x15, 0x98, 0x48, 0xc2, 0x28, 0x51, 0x8d, 0x0d, 0xb8, 0xa2, + 0x92, 0x05, 0x59, 0x1d, 0x5e, 0x97, 0x90, 0xb1, 0x58, 0x52, 0x18, 0xb5, 0x0b, 0x60, 0x5c, 0x94, + 0xf7, 0xe6, 0x4b, 0x0d, 0x94, 0xb6, 0x13, 0x73, 0x5b, 0x9e, 0x0b, 0xef, 0x25, 0x5f, 0x4a, 0x19, + 0xb9, 0x00, 0x2e, 0x0f, 0xfd, 0x96, 0xac, 0x18, 0xfd, 0xac, 0x4c, 0x6a, 0xd6, 0xb5, 0x0f, 0x34, + 0xf8, 0x19, 0x98, 0xd8, 0xc3, 0x1e, 0xf5, 0x99, 0xf8, 0x5e, 0x07, 0xb0, 0x27, 0x08, 0xe9, 0xd7, + 0x7e, 0x65, 0xb1, 0xaf, 0xec, 0xb7, 0x39, 0xee, 0xda, 0xce, 0x6f, 0xaf, 0xcb, 0xda, 0xab, 0xd7, + 0x65, 0xed, 0xaf, 0xd7, 0x65, 0xed, 0xc5, 0x69, 0x79, 0xe4, 0xd5, 0x69, 0x79, 0xe4, 0x8f, 0xd3, + 0xf2, 0xc8, 0x37, 0xd5, 0x86, 0xcb, 0x9e, 0x84, 0xb6, 0x59, 0xa7, 0xad, 0xe4, 0xc7, 0x36, 0xcf, + 0xa7, 0x87, 0xb8, 0xce, 0x92, 0x53, 0xb5, 0xe7, 0x57, 0x3b, 0x3b, 0x2f, 0x4c, 0x5f, 0xff, 0x27, + 0x00, 0x00, 0xff, 0xff, 0x30, 0x4b, 0x0b, 0x1d, 0xcf, 0x13, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1543,6 +1558,18 @@ func (m *JobRunLease) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.JobRunIndex != nil { + { + size, err := m.JobRunIndex.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintExecutorapi(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } if len(m.JobRunId) > 0 { i -= len(m.JobRunId) copy(dAtA[i:], m.JobRunId) @@ -2070,6 +2097,10 @@ func (m *JobRunLease) Size() (n int) { if l > 0 { n += 1 + l + sovExecutorapi(uint64(l)) } + if m.JobRunIndex != nil { + l = m.JobRunIndex.Size() + n += 1 + l + sovExecutorapi(uint64(l)) + } return n } @@ -4343,6 +4374,42 @@ func (m *JobRunLease) Unmarshal(dAtA []byte) error { } m.JobRunId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JobRunIndex", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExecutorapi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExecutorapi + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthExecutorapi + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.JobRunIndex == nil { + m.JobRunIndex = &types.UInt32Value{} + } + if err := m.JobRunIndex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipExecutorapi(dAtA[iNdEx:]) diff --git a/pkg/executorapi/executorapi.proto b/pkg/executorapi/executorapi.proto index 58fa4aa7cf6..db351c52d96 100644 --- a/pkg/executorapi/executorapi.proto +++ b/pkg/executorapi/executorapi.proto @@ -6,6 +6,7 @@ option go_package = "github.com/armadaproject/armada/pkg/executorapi"; import "pkg/armadaevents/events.proto"; import "pkg/api/submit.proto"; import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; import "k8s.io/api/core/v1/generated.proto"; import "k8s.io/apimachinery/pkg/api/resource/generated.proto"; @@ -79,6 +80,12 @@ message JobRunLease{ repeated string groups = 5; armadaevents.SubmitJob job = 6; string job_run_id = 7; + // job_run_index is the zero-based attempt counter for this run within its job. + // Wrapped to give explicit presence: nil means the scheduler did not populate + // the field (legacy scheduler or feature flag off), so the executor must use + // the legacy pod-name format. Non-nil means the executor must include the + // index as a suffix in the pod name to disambiguate retry attempts. + google.protobuf.UInt32Value job_run_index = 8; } // Indicates that the job runs with the given ids should be cancelled. From 105f55f2722a8b724edb3c0b676d0b29bcea4f6c Mon Sep 17 00:00:00 2001 From: Dejan Zele Pejchev Date: Fri, 8 May 2026 15:05:11 +0200 Subject: [PATCH 4/5] Wire retry policy engine into scheduler Signed-off-by: Dejan Zele Pejchev --- internal/scheduler/jobdb/job.go | 15 + internal/scheduler/retry/cache.go | 99 +++++ internal/scheduler/retry/convert.go | 101 +++++ internal/scheduler/retry/convert_test.go | 160 ++++++++ internal/scheduler/retry_policy_test.go | 468 +++++++++++++++++++++++ internal/scheduler/scheduler.go | 168 +++++++- internal/scheduler/scheduler_test.go | 14 + internal/scheduler/schedulerapp.go | 25 ++ 8 files changed, 1045 insertions(+), 5 deletions(-) create mode 100644 internal/scheduler/retry/cache.go create mode 100644 internal/scheduler/retry/convert.go create mode 100644 internal/scheduler/retry/convert_test.go create mode 100644 internal/scheduler/retry_policy_test.go diff --git a/internal/scheduler/jobdb/job.go b/internal/scheduler/jobdb/job.go index f103ec3c93f..3476fb2840a 100644 --- a/internal/scheduler/jobdb/job.go +++ b/internal/scheduler/jobdb/job.go @@ -844,6 +844,21 @@ func (job *Job) NumAttempts() uint { return attempts } +// FailureCount returns the number of runs of this job that have ended in a +// failed terminal state. The retry engine treats this value as the per-policy +// failure counter for limit enforcement; we derive it from run history rather +// than maintain a separate counter so it survives scheduler restarts (the +// same is not true of in-memory-only counters). +func (job *Job) FailureCount() uint32 { + count := uint32(0) + for _, run := range job.runsById { + if run.failed { + count++ + } + } + return count +} + // AllRuns returns all runs associated with job. func (job *Job) AllRuns() []*JobRun { return maps.Values(job.runsById) diff --git a/internal/scheduler/retry/cache.go b/internal/scheduler/retry/cache.go new file mode 100644 index 00000000000..6901aba0588 --- /dev/null +++ b/internal/scheduler/retry/cache.go @@ -0,0 +1,99 @@ +package retry + +import ( + "fmt" + "sync/atomic" + "time" + + "github.com/armadaproject/armada/internal/common/armadacontext" + "github.com/armadaproject/armada/pkg/api" +) + +// PolicyCache is the read-side interface the scheduler uses to look up +// compiled retry policies by name. +type PolicyCache interface { + // Get returns the compiled policy for the given name. Returns (nil, false) + // when the name is empty, the cache is empty, or the policy is unknown. + Get(name string) (*Policy, bool) +} + +// ApiPolicyCache periodically fetches retry policies from the Armada API and +// keeps a compiled, in-memory copy. The cache fails open: if the API is +// unreachable the previously-cached policies are still served. +type ApiPolicyCache struct { + updateFrequency time.Duration + apiClient api.RetryPolicyServiceClient + policies atomic.Pointer[map[string]*Policy] +} + +// NewApiPolicyCache creates an ApiPolicyCache. updateFrequency should mirror +// the QueueCache cadence in the scheduler app wiring. +func NewApiPolicyCache(apiClient api.RetryPolicyServiceClient, updateFrequency time.Duration) *ApiPolicyCache { + return &ApiPolicyCache{ + updateFrequency: updateFrequency, + apiClient: apiClient, + } +} + +// Initialise blocks once to populate the cache before the scheduler starts. +func (c *ApiPolicyCache) Initialise(ctx *armadacontext.Context) error { + return c.fetch(ctx) +} + +// Run refreshes the cache on the configured interval until ctx is cancelled. +// Errors are logged but do not stop the loop, consistent with QueueCache.Run. +// The first refresh happens on the first tick; call Initialise to prime. +func (c *ApiPolicyCache) Run(ctx *armadacontext.Context) error { + ticker := time.NewTicker(c.updateFrequency) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return nil + case <-ticker.C: + if err := c.fetch(ctx); err != nil { + ctx.Warnf("error fetching retry policies: %v", err) + } + } + } +} + +func (c *ApiPolicyCache) Get(name string) (*Policy, bool) { + if name == "" { + return nil, false + } + m := c.policies.Load() + if m == nil { + return nil, false + } + policy, ok := (*m)[name] + return policy, ok +} + +func (c *ApiPolicyCache) fetch(ctx *armadacontext.Context) error { + start := time.Now() + resp, err := c.apiClient.GetRetryPolicies(ctx, &api.RetryPolicyListRequest{}) + if err != nil { + return fmt.Errorf("get retry policies: %w", err) + } + compiled := make(map[string]*Policy, len(resp.RetryPolicies)) + for _, p := range resp.RetryPolicies { + policy, err := ConvertPolicy(p) + if err != nil { + // One bad policy must not poison the entire cache; log and skip. + ctx.Warnf("skipping invalid retry policy %q: %v", p.GetName(), err) + continue + } + compiled[p.Name] = policy + } + c.policies.Store(&compiled) + ctx.Infof("Refreshed %d retry policies in %s", len(compiled), time.Since(start)) + return nil +} + +// NoopPolicyCache always reports the policy as missing. Used when the retry +// policy feature is disabled so the scheduler falls through to the legacy +// failure path. +type NoopPolicyCache struct{} + +func (NoopPolicyCache) Get(string) (*Policy, bool) { return nil, false } diff --git a/internal/scheduler/retry/convert.go b/internal/scheduler/retry/convert.go new file mode 100644 index 00000000000..7f313558aaa --- /dev/null +++ b/internal/scheduler/retry/convert.go @@ -0,0 +1,101 @@ +package retry + +import ( + "fmt" + + "github.com/armadaproject/armada/internal/common/errormatch" + "github.com/armadaproject/armada/pkg/api" +) + +// ConvertPolicy translates an api.RetryPolicy proto into the internal Policy, +// validating fields and pre-compiling regex patterns via CompileRules. +// Returns an error for any malformed field (invalid regex, unknown action, +// missing values, etc.). +func ConvertPolicy(p *api.RetryPolicy) (*Policy, error) { + if p == nil { + return nil, fmt.Errorf("retry policy is nil") + } + + defaultAction, err := convertAction(p.DefaultAction) + if err != nil { + return nil, fmt.Errorf("default_action: %w", err) + } + + rules := make([]Rule, 0, len(p.Rules)) + for i, r := range p.Rules { + converted, err := convertRule(r) + if err != nil { + return nil, fmt.Errorf("rule %d: %w", i, err) + } + rules = append(rules, converted) + } + + policy := &Policy{ + Name: p.Name, + RetryLimit: p.RetryLimit, + DefaultAction: defaultAction, + Rules: rules, + } + if err := CompileRules(policy.Rules); err != nil { + return nil, fmt.Errorf("policy %q: %w", p.Name, err) + } + return policy, nil +} + +func convertAction(a api.RetryAction) (Action, error) { + switch a { + case api.RetryAction_RETRY_ACTION_FAIL: + return ActionFail, nil + case api.RetryAction_RETRY_ACTION_RETRY: + return ActionRetry, nil + default: + // Treat RETRY_ACTION_UNSPECIFIED and any unknown value as a hard + // error; silently defaulting could turn a truncated proto into a + // policy that retries everything. + return "", fmt.Errorf("unknown action %q", a.String()) + } +} + +func convertRule(r *api.RetryRule) (Rule, error) { + if r == nil { + return Rule{}, fmt.Errorf("rule is nil") + } + action, err := convertAction(r.Action) + if err != nil { + return Rule{}, fmt.Errorf("action: %w", err) + } + + // Deep-copy slices so the cached Policy does not retain references into + // the API response (which becomes GC-eligible after this call returns). + rule := Rule{ + Action: action, + OnConditions: append([]string(nil), r.OnConditions...), + OnCategory: r.OnCategory, + OnSubcategory: r.OnSubcategory, + } + if r.OnExitCodes != nil { + op, err := convertExitCodeOperator(r.OnExitCodes.Operator) + if err != nil { + return Rule{}, fmt.Errorf("on_exit_codes: %w", err) + } + rule.OnExitCodes = &errormatch.ExitCodeMatcher{ + Operator: op, + Values: append([]int32(nil), r.OnExitCodes.Values...), + } + } + if r.OnTerminationMessagePattern != "" { + rule.OnTerminationMessage = &errormatch.RegexMatcher{Pattern: r.OnTerminationMessagePattern} + } + return rule, nil +} + +func convertExitCodeOperator(op api.ExitCodeOperator) (errormatch.ExitCodeOperator, error) { + switch op { + case api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN: + return errormatch.ExitCodeOperatorIn, nil + case api.ExitCodeOperator_EXIT_CODE_OPERATOR_NOT_IN: + return errormatch.ExitCodeOperatorNotIn, nil + default: + return "", fmt.Errorf("unknown operator %q", op.String()) + } +} diff --git a/internal/scheduler/retry/convert_test.go b/internal/scheduler/retry/convert_test.go new file mode 100644 index 00000000000..057eb9f0eed --- /dev/null +++ b/internal/scheduler/retry/convert_test.go @@ -0,0 +1,160 @@ +package retry + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/armadaproject/armada/internal/common/errormatch" + "github.com/armadaproject/armada/pkg/api" +) + +func TestConvertPolicy_RoundTripAllMatchTypes(t *testing.T) { + proto := &api.RetryPolicy{ + Name: "policy-1", + RetryLimit: 5, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{ + { + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnConditions: []string{errormatch.ConditionOOMKilled}, + }, + { + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnExitCodes: &api.RetryExitCodeMatcher{ + Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN, + Values: []int32{42, 137}, + }, + }, + { + Action: api.RetryAction_RETRY_ACTION_FAIL, + OnTerminationMessagePattern: "(?i)out of memory", + }, + { + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnCategory: "transient", + OnSubcategory: "node-failure", + }, + }, + } + + policy, err := ConvertPolicy(proto) + require.NoError(t, err) + require.NotNil(t, policy) + + assert.Equal(t, "policy-1", policy.Name) + assert.Equal(t, uint32(5), policy.RetryLimit) + assert.Equal(t, ActionFail, policy.DefaultAction) + require.Len(t, policy.Rules, 4) + + // Conditions rule. + assert.Equal(t, ActionRetry, policy.Rules[0].Action) + assert.Equal(t, []string{errormatch.ConditionOOMKilled}, policy.Rules[0].OnConditions) + + // Exit-code rule. + assert.Equal(t, ActionRetry, policy.Rules[1].Action) + require.NotNil(t, policy.Rules[1].OnExitCodes) + assert.Equal(t, errormatch.ExitCodeOperatorIn, policy.Rules[1].OnExitCodes.Operator) + assert.Equal(t, []int32{42, 137}, policy.Rules[1].OnExitCodes.Values) + + // Termination-message rule. + assert.Equal(t, ActionFail, policy.Rules[2].Action) + require.NotNil(t, policy.Rules[2].OnTerminationMessage) + assert.Equal(t, "(?i)out of memory", policy.Rules[2].OnTerminationMessage.Pattern) + require.NotNil(t, policy.Rules[2].compiledTerminationMessage, + "CompileRules must populate compiledTerminationMessage so the matcher does not fail closed at evaluation time") + + // Category rule. + assert.Equal(t, ActionRetry, policy.Rules[3].Action) + assert.Equal(t, "transient", policy.Rules[3].OnCategory) + assert.Equal(t, "node-failure", policy.Rules[3].OnSubcategory) +} + +func TestConvertPolicy_EmptyFieldsRemainEmpty(t *testing.T) { + // Smoke test guarding against a common nil-vs-empty bug: proto3 omits + // scalar zero values, so an unset on_subcategory deserialises as "" and + // must remain "" on the engine Rule (not nil, not ""). + proto := &api.RetryPolicy{ + Name: "empty-fields", + RetryLimit: 1, + DefaultAction: api.RetryAction_RETRY_ACTION_RETRY, + Rules: []*api.RetryRule{ + { + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnCategory: "kubernetes", + // OnSubcategory and other fields intentionally left zero. + }, + }, + } + + policy, err := ConvertPolicy(proto) + require.NoError(t, err) + require.Len(t, policy.Rules, 1) + rule := policy.Rules[0] + assert.Equal(t, "kubernetes", rule.OnCategory) + assert.Equal(t, "", rule.OnSubcategory) + assert.Empty(t, rule.OnConditions) + assert.Nil(t, rule.OnExitCodes) + assert.Nil(t, rule.OnTerminationMessage) +} + +func TestConvertPolicy_InvalidRegex(t *testing.T) { + proto := &api.RetryPolicy{ + Name: "bad-regex", + RetryLimit: 1, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{ + { + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnTerminationMessagePattern: "(unclosed", + }, + }, + } + + policy, err := ConvertPolicy(proto) + assert.Nil(t, policy) + require.Error(t, err) + assert.Contains(t, err.Error(), "bad-regex", + "error must mention the policy name so operators can locate the broken policy") +} + +func TestConvertPolicy_UnknownAction(t *testing.T) { + proto := &api.RetryPolicy{ + Name: "unspecified", + RetryLimit: 1, + DefaultAction: api.RetryAction_RETRY_ACTION_UNSPECIFIED, + Rules: nil, + } + _, err := ConvertPolicy(proto) + require.Error(t, err) + // We refuse RETRY_ACTION_UNSPECIFIED rather than treating it as a default, + // otherwise a truncated proto could silently retry every error. + assert.True(t, strings.Contains(err.Error(), "unknown action"), err.Error()) +} + +func TestConvertPolicy_NilProto(t *testing.T) { + policy, err := ConvertPolicy(nil) + assert.Nil(t, policy) + require.Error(t, err) +} + +func TestConvertPolicy_InvalidExitCodeOperator(t *testing.T) { + proto := &api.RetryPolicy{ + Name: "bad-op", + RetryLimit: 1, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{ + { + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnExitCodes: &api.RetryExitCodeMatcher{ + Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_UNSPECIFIED, + Values: []int32{1}, + }, + }, + }, + } + _, err := ConvertPolicy(proto) + require.Error(t, err) +} diff --git a/internal/scheduler/retry_policy_test.go b/internal/scheduler/retry_policy_test.go new file mode 100644 index 00000000000..2d7ebc7d513 --- /dev/null +++ b/internal/scheduler/retry_policy_test.go @@ -0,0 +1,468 @@ +package scheduler + +import ( + "testing" + "time" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + clock "k8s.io/utils/clock/testing" + + "github.com/armadaproject/armada/internal/common/armadacontext" + "github.com/armadaproject/armada/internal/common/util" + schedulerconfig "github.com/armadaproject/armada/internal/scheduler/configuration" + "github.com/armadaproject/armada/internal/scheduler/jobdb" + "github.com/armadaproject/armada/internal/scheduler/leader" + "github.com/armadaproject/armada/internal/scheduler/pricing" + "github.com/armadaproject/armada/internal/scheduler/retry" + "github.com/armadaproject/armada/internal/scheduler/testfixtures" + "github.com/armadaproject/armada/pkg/api" + "github.com/armadaproject/armada/pkg/armadaevents" +) + +// fakePolicyCache backs the retry-policy lookup with a fixed in-memory map. +// Tests use this to drive the engine's failure-handling path without going +// through the gRPC cache implementation. +type fakePolicyCache map[string]*retry.Policy + +func (c fakePolicyCache) Get(name string) (*retry.Policy, bool) { + if p, ok := c[name]; ok { + return p, true + } + return nil, false +} + +// makeRetryTestScheduler builds a Scheduler wired with the bare minimum +// dependencies needed to exercise the failure path through +// generateUpdateMessagesFromJob. The legacy maxAttemptedRuns and the queue +// cache are still needed even with the feature flag off, so we set them. +func makeRetryTestScheduler(t *testing.T, ffEnabled bool, policyCache retry.PolicyCache) *Scheduler { + return makeRetryTestSchedulerWithGlobalMax(t, ffEnabled, policyCache, 0) +} + +// makeRetryTestSchedulerWithGlobalMax is the same as makeRetryTestScheduler +// but lets the caller set the global retry cap, used to pin the contract +// that the cap counts failed runs only. +func makeRetryTestSchedulerWithGlobalMax(t *testing.T, ffEnabled bool, policyCache retry.PolicyCache, globalMaxRetries uint) *Scheduler { + t.Helper() + jobDb := testfixtures.NewJobDb(testfixtures.TestResourceListFactory) + + queueCache := &testQueueCache{queues: []*api.Queue{ + {Name: "testQueue", RetryPolicy: "test-policy"}, + }} + + sched, err := NewScheduler( + jobDb, + &testJobRepository{}, + &testExecutorRepository{}, + &testSchedulingAlgo{}, + leader.NewStandaloneLeaderController(), + newTestPublisher(), + &testSubmitChecker{checkSuccess: true}, + &testGangValidator{validateSuccess: true}, + 1*time.Second, + 5*time.Second, + 1*time.Hour, + nil, + maxNumberOfAttempts, + nodeIdLabel, + schedulerMetrics, + pricing.NoopBidPriceProvider{}, + []string{}, + queueCache, + schedulerconfig.RetryPolicyConfig{Enabled: ffEnabled, GlobalMaxRetries: globalMaxRetries}, + policyCache, + ) + require.NoError(t, err) + sched.clock = clock.NewFakeClock(time.Now()) + return sched +} + +// makeFailedJobForRetry builds a job with one failed run, ready for the +// failure-handling code path to evaluate. +func makeFailedJobForRetry(t *testing.T, sched *Scheduler) *jobdb.Job { + t.Helper() + jobId := util.NewULID() + job := testfixtures.NewJob( + jobId, + "testJobset", + "testQueue", + uint32(10), + toInternalSchedulingInfo(schedulingInfo), + false, // queued + 1, // queuedVersion + false, false, false, + 1, // created + true, // validated + ) + failedRun := sched.jobDb.CreateRun( + uuid.NewString(), + 0, // index + jobId, + 1, // creationTime + "testExecutor", + "testNodeId", + "testNode", + "testPool", + nil, + false, false, false, false, nil, + false, // preempted + false, // succeeded + true, // failed + false, // cancelled + nil, nil, nil, nil, nil, + false, // returned (not lease-returned) + false, // runAttempted + ) + return job.WithUpdatedRun(failedRun) +} + +func containerErrorWithExitCode(code int32) *armadaevents.Error { + return &armadaevents.Error{ + Reason: &armadaevents.Error_PodError{ + PodError: &armadaevents.PodError{ + ContainerErrors: []*armadaevents.ContainerError{ + { + ExitCode: code, + Message: "exit", + }, + }, + KubernetesReason: armadaevents.KubernetesReason_AppError, + }, + }, + } +} + +func TestRetryPolicy_FFOff_NoEngineEvaluation(t *testing.T) { + policy, err := retry.ConvertPolicy(&api.RetryPolicy{ + Name: "test-policy", + RetryLimit: 3, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{{ + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnExitCodes: &api.RetryExitCodeMatcher{Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN, Values: []int32{42}}, + }}, + }) + require.NoError(t, err) + + sched := makeRetryTestScheduler(t, false, fakePolicyCache{"test-policy": policy}) + job := makeFailedJobForRetry(t, sched) + + txn := sched.jobDb.WriteTxn() + defer txn.Abort() + require.NoError(t, txn.Upsert([]*jobdb.Job{job})) + + jobErrors := map[string]*armadaevents.Error{job.LatestRun().Id(): containerErrorWithExitCode(42)} + + events, err := sched.generateUpdateMessagesFromJob(armadacontext.Background(), job, jobErrors, nil, txn) + require.NoError(t, err) + require.NotNil(t, events) + + hasRequeue, hasErrors := classifyEvents(events.Events) + assert.False(t, hasRequeue, "FF off must not emit JobRequeued via engine") + assert.True(t, hasErrors, "FF off must still emit terminal JobErrors") +} + +func TestRetryPolicy_FFOn_RetryDecision(t *testing.T) { + policy, err := retry.ConvertPolicy(&api.RetryPolicy{ + Name: "test-policy", + RetryLimit: 3, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{{ + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnExitCodes: &api.RetryExitCodeMatcher{Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN, Values: []int32{42}}, + }}, + }) + require.NoError(t, err) + + sched := makeRetryTestScheduler(t, true, fakePolicyCache{"test-policy": policy}) + job := makeFailedJobForRetry(t, sched) + + txn := sched.jobDb.WriteTxn() + defer txn.Abort() + require.NoError(t, txn.Upsert([]*jobdb.Job{job})) + + jobErrors := map[string]*armadaevents.Error{job.LatestRun().Id(): containerErrorWithExitCode(42)} + queueRetryPolicies := map[string]string{"testQueue": "test-policy"} + + events, err := sched.generateUpdateMessagesFromJob(armadacontext.Background(), job, jobErrors, queueRetryPolicies, txn) + require.NoError(t, err) + require.NotNil(t, events) + + hasRequeue, hasErrors := classifyEvents(events.Events) + assert.True(t, hasRequeue, "FF on with matching retry rule must emit JobRequeued") + assert.True(t, hasErrors, "FF on with retry decision must emit a non-terminal JobErrors so the api event stream surfaces the retry") + assert.False(t, hasTerminalError(events.Events), "the emitted JobErrors must be non-terminal (Terminal=false) so it converts to JobFailedEvent{retryable=true}") + + // Simulate the next scheduling cycle creating a new run and assert the + // run index advances. The scheduler-side WithNewRun derives index from + // len(runsById), so the second run must be index 1. + updatedJob := txn.GetById(job.Id()) + require.NotNil(t, updatedJob) + relaunched := updatedJob.WithQueued(false).WithNewRun("testExecutor", "testNodeId", "testNode", "testPool", 0) + assert.Equal(t, uint32(1), relaunched.LatestRun().Index(), + "the executor pod-name suffix must change on retry: index 0 then index 1") +} + +func TestRetryPolicy_FFOn_PolicyLimitCapsRetries(t *testing.T) { + policy, err := retry.ConvertPolicy(&api.RetryPolicy{ + Name: "test-policy", + RetryLimit: 2, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{{ + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnExitCodes: &api.RetryExitCodeMatcher{Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN, Values: []int32{42}}, + }}, + }) + require.NoError(t, err) + + sched := makeRetryTestScheduler(t, true, fakePolicyCache{"test-policy": policy}) + + // retryLimit=2 means 2 retries are allowed. With three failed runs already + // (initial + 2 retries), the policy cap must trip on the next evaluation. + jobId := util.NewULID() + job := testfixtures.NewJob(jobId, "testJobset", "testQueue", uint32(10), toInternalSchedulingInfo(schedulingInfo), false, 1, false, false, false, 1, true) + for i := uint32(0); i < 3; i++ { + failedRun := sched.jobDb.CreateRun(uuid.NewString(), i, jobId, 1, "testExecutor", "testNodeId", "testNode", "testPool", nil, + false, false, false, false, nil, false, false, true, false, nil, nil, nil, nil, nil, false, false) + job = job.WithUpdatedRun(failedRun) + } + require.Equal(t, uint32(3), job.FailureCount()) + + txn := sched.jobDb.WriteTxn() + defer txn.Abort() + require.NoError(t, txn.Upsert([]*jobdb.Job{job})) + + jobErrors := map[string]*armadaevents.Error{job.LatestRun().Id(): containerErrorWithExitCode(42)} + queueRetryPolicies := map[string]string{"testQueue": "test-policy"} + + events, err := sched.generateUpdateMessagesFromJob(armadacontext.Background(), job, jobErrors, queueRetryPolicies, txn) + require.NoError(t, err) + require.NotNil(t, events) + + hasRequeue, _ := classifyEvents(events.Events) + assert.False(t, hasRequeue, "engine at retry limit must not emit JobRequeued") + msg := terminalErrorMessage(events.Events) + assert.Contains(t, msg, "Retry policy:", + "terminal failure must surface the engine reason (operators rely on it for audit)") + assert.Contains(t, msg, "policy retry limit", + "reason must indicate the policy retry limit was hit") +} + +func TestRetryPolicy_FFOn_TerminalFailPreservesFailureCategory(t *testing.T) { + policy, err := retry.ConvertPolicy(&api.RetryPolicy{ + Name: "test-policy", + RetryLimit: 0, // unlimited at policy level + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{{ + Action: api.RetryAction_RETRY_ACTION_FAIL, + OnExitCodes: &api.RetryExitCodeMatcher{Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN, Values: []int32{42}}, + }}, + }) + require.NoError(t, err) + + sched := makeRetryTestScheduler(t, true, fakePolicyCache{"test-policy": policy}) + job := makeFailedJobForRetry(t, sched) + + txn := sched.jobDb.WriteTxn() + defer txn.Abort() + require.NoError(t, txn.Upsert([]*jobdb.Job{job})) + + runError := containerErrorWithExitCode(42) + runError.FailureCategory = "ApplicationError" + runError.FailureSubcategory = "ExitCode42" + jobErrors := map[string]*armadaevents.Error{job.LatestRun().Id(): runError} + queueRetryPolicies := map[string]string{"testQueue": "test-policy"} + + events, err := sched.generateUpdateMessagesFromJob(armadacontext.Background(), job, jobErrors, queueRetryPolicies, txn) + require.NoError(t, err) + require.NotNil(t, events) + + for _, e := range events.Events { + if je := e.GetJobErrors(); je != nil { + for _, errEv := range je.Errors { + if !errEv.Terminal { + continue + } + assert.Equal(t, "ApplicationError", errEv.FailureCategory, + "policy-fail terminal error must carry the original FailureCategory") + assert.Equal(t, "ExitCode42", errEv.FailureSubcategory, + "policy-fail terminal error must carry the original FailureSubcategory") + return + } + } + } + t.Fatal("expected a terminal JobErrors event") +} + +func TestRetryPolicy_FFOn_MissingPolicyFallsThrough(t *testing.T) { + sched := makeRetryTestScheduler(t, true, fakePolicyCache{}) // empty cache + + job := makeFailedJobForRetry(t, sched) + txn := sched.jobDb.WriteTxn() + defer txn.Abort() + require.NoError(t, txn.Upsert([]*jobdb.Job{job})) + + jobErrors := map[string]*armadaevents.Error{job.LatestRun().Id(): containerErrorWithExitCode(42)} + queueRetryPolicies := map[string]string{"testQueue": "test-policy"} + + events, err := sched.generateUpdateMessagesFromJob(armadacontext.Background(), job, jobErrors, queueRetryPolicies, txn) + require.NoError(t, err) + require.NotNil(t, events) + + _, hasErrors := classifyEvents(events.Events) + assert.True(t, hasErrors, "missing policy must not crash; falls back to legacy terminal-failure path") +} + +func classifyEvents(events []*armadaevents.EventSequence_Event) (hasRequeue bool, hasErrors bool) { + for _, e := range events { + if e.GetJobRequeued() != nil { + hasRequeue = true + } + if e.GetJobErrors() != nil { + hasErrors = true + } + } + return +} + +// hasTerminalError reports whether any emitted JobErrors carries a terminal +// Error - the engine retry path must emit only non-terminal errors so the +// api conversion stamps retryable=true on the resulting JobFailedEvent. +func hasTerminalError(events []*armadaevents.EventSequence_Event) bool { + for _, e := range events { + je := e.GetJobErrors() + if je == nil { + continue + } + for _, errEv := range je.Errors { + if errEv.Terminal { + return true + } + } + } + return false +} + +func terminalErrorMessage(events []*armadaevents.EventSequence_Event) string { + for _, e := range events { + if je := e.GetJobErrors(); je != nil { + for _, errEv := range je.Errors { + if mre := errEv.GetMaxRunsExceeded(); mre != nil { + return mre.Message + } + } + } + } + return "" +} + +// TestRetryPolicy_FFOn_GangJobSkipped pins gang skip; see +// notes/retry-policy/gang-retry.md for why gangs are out of scope. +func TestRetryPolicy_FFOn_GangJobSkipped(t *testing.T) { + policy, err := retry.ConvertPolicy(&api.RetryPolicy{ + Name: "test-policy", + RetryLimit: 3, + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{{ + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnExitCodes: &api.RetryExitCodeMatcher{Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN, Values: []int32{42}}, + }}, + }) + require.NoError(t, err) + + sched := makeRetryTestScheduler(t, true, fakePolicyCache{"test-policy": policy}) + job := makeFailedJobForRetry(t, sched).WithGangInfo(jobdb.CreateGangInfo("gang-1", 3, "")) + require.True(t, job.IsInGang(), "test fixture must produce a gang job") + + txn := sched.jobDb.WriteTxn() + defer txn.Abort() + require.NoError(t, txn.Upsert([]*jobdb.Job{job})) + + jobErrors := map[string]*armadaevents.Error{job.LatestRun().Id(): containerErrorWithExitCode(42)} + queueRetryPolicies := map[string]string{"testQueue": "test-policy"} + + events, err := sched.generateUpdateMessagesFromJob(armadacontext.Background(), job, jobErrors, queueRetryPolicies, txn) + require.NoError(t, err) + require.NotNil(t, events) + + hasRequeue, hasErrors := classifyEvents(events.Events) + assert.False(t, hasRequeue, "gang job must NOT be requeued by the engine") + assert.True(t, hasErrors, "gang job must reach terminal failure via legacy path") +} + +// TestRetryPolicy_FFOn_PreemptedRunsDoNotCountAgainstGlobalCap guards against +// the scheduler-algo's fresh-run-per-preemption shape (preempted=true, +// failed=false) burning global-cap budget before any policy retry happened. +func TestRetryPolicy_FFOn_PreemptedRunsDoNotCountAgainstGlobalCap(t *testing.T) { + policy, err := retry.ConvertPolicy(&api.RetryPolicy{ + Name: "test-policy", + RetryLimit: 0, // unlimited at policy level; global cap is the only gate + DefaultAction: api.RetryAction_RETRY_ACTION_FAIL, + Rules: []*api.RetryRule{{ + Action: api.RetryAction_RETRY_ACTION_RETRY, + OnExitCodes: &api.RetryExitCodeMatcher{Operator: api.ExitCodeOperator_EXIT_CODE_OPERATOR_IN, Values: []int32{42}}, + }}, + }) + require.NoError(t, err) + + // Global cap of 2: with the bug, three preempted-but-not-failed runs plus + // one failed run (totalRuns=4) would trip the cap. With the fix + // (totalRuns counts only failed=true), failureCount=1 < 2 retries. + sched := makeRetryTestSchedulerWithGlobalMax(t, true, fakePolicyCache{"test-policy": policy}, 2) + + jobId := util.NewULID() + job := testfixtures.NewJob( + jobId, "testJobset", "testQueue", uint32(10), + toInternalSchedulingInfo(schedulingInfo), + false, 1, false, false, false, 1, true, + ) + // Add three preempted-but-not-failed runs - the scheduler-algo preemption + // shape that creates new runs without burning policy-retry budget. + for i := 0; i < 3; i++ { + preemptedRun := sched.jobDb.CreateRun( + uuid.NewString(), uint32(i), jobId, 1, + "testExecutor", "testNodeId", "testNode", "testPool", + nil, false, false, false, false, nil, + true, // preempted + false, // succeeded + false, // failed + false, // cancelled + nil, nil, nil, nil, nil, + false, false, + ) + job = job.WithUpdatedRun(preemptedRun) + } + // Add a single failed run that the engine will evaluate. + failedRun := sched.jobDb.CreateRun( + uuid.NewString(), 3, jobId, 1, + "testExecutor", "testNodeId", "testNode", "testPool", + nil, false, false, false, false, nil, + false, // preempted + false, // succeeded + true, // failed + false, // cancelled + nil, nil, nil, nil, nil, + false, false, + ) + job = job.WithUpdatedRun(failedRun) + require.Equal(t, uint32(1), job.FailureCount(), "fixture must have exactly one failed run") + require.Equal(t, 4, len(job.AllRuns()), "fixture must have four total runs") + + txn := sched.jobDb.WriteTxn() + defer txn.Abort() + require.NoError(t, txn.Upsert([]*jobdb.Job{job})) + + jobErrors := map[string]*armadaevents.Error{job.LatestRun().Id(): containerErrorWithExitCode(42)} + queueRetryPolicies := map[string]string{"testQueue": "test-policy"} + + events, err := sched.generateUpdateMessagesFromJob(armadacontext.Background(), job, jobErrors, queueRetryPolicies, txn) + require.NoError(t, err) + require.NotNil(t, events) + + hasRequeue, _ := classifyEvents(events.Events) + assert.True(t, hasRequeue, + "global cap must measure failures, not preempted runs; with 1 failure under a cap of 2 the engine must still retry") + assert.False(t, hasTerminalError(events.Events), "engine retry path must not emit a terminal JobErrors") +} diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index 7ca9db4dfa9..12b1e306929 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -15,6 +15,7 @@ import ( "github.com/armadaproject/armada/internal/common/constants" protoutil "github.com/armadaproject/armada/internal/common/proto" armadaslices "github.com/armadaproject/armada/internal/common/slices" + "github.com/armadaproject/armada/internal/scheduler/configuration" "github.com/armadaproject/armada/internal/scheduler/database" "github.com/armadaproject/armada/internal/scheduler/internaltypes" "github.com/armadaproject/armada/internal/scheduler/jobdb" @@ -23,6 +24,7 @@ import ( "github.com/armadaproject/armada/internal/scheduler/metrics" "github.com/armadaproject/armada/internal/scheduler/pricing" "github.com/armadaproject/armada/internal/scheduler/queue" + "github.com/armadaproject/armada/internal/scheduler/retry" "github.com/armadaproject/armada/internal/scheduler/schedulerobjects" "github.com/armadaproject/armada/internal/scheduler/scheduling" schedulercontext "github.com/armadaproject/armada/internal/scheduler/scheduling/context" @@ -92,6 +94,17 @@ type Scheduler struct { marketDrivenPools []string // Used to look up queue state (e.g., cordoned status) queueCache queue.QueueCache + // Retry policy configuration. When retryPolicyConfig.Enabled is true, the + // scheduler consults the engine on every run failure; otherwise the + // failure-handling path is identical to the pre-feature behaviour. + retryPolicyConfig configuration.RetryPolicyConfig + // Compiled retry-policy lookup, populated by the cache loop. Always + // non-nil; a NoopPolicyCache is used when the feature flag is off so we + // never need a nil check at the call site. + retryPolicyCache retry.PolicyCache + // Engine evaluating retry decisions. Always non-nil so the call site can + // invoke Evaluate without a nil-guard. + retryEngine *retry.Engine } func NewScheduler( @@ -113,7 +126,15 @@ func NewScheduler( bidPriceProvider pricing.BidPriceProvider, marketDrivenPools []string, queueCache queue.QueueCache, + retryPolicyConfig configuration.RetryPolicyConfig, + retryPolicyCache retry.PolicyCache, ) (*Scheduler, error) { + if retryPolicyCache == nil { + // Always non-nil so callers in the failure path do not need a nil + // check; NoopPolicyCache reports every name as missing, which makes + // the engine call fall through to the legacy path. + retryPolicyCache = retry.NoopPolicyCache{} + } return &Scheduler{ jobRepository: jobRepository, executorRepository: executorRepository, @@ -136,6 +157,9 @@ func NewScheduler( metrics: metrics, marketDrivenPools: marketDrivenPools, queueCache: queueCache, + retryPolicyConfig: retryPolicyConfig, + retryPolicyCache: retryPolicyCache, + retryEngine: retry.NewEngine(retryPolicyConfig.GlobalMaxRetries), }, nil } @@ -785,6 +809,7 @@ func AppendEventSequencesFromScheduledJobs(eventSequences []*armadaevents.EventS Event: &armadaevents.EventSequence_Event_JobRunLeased{ JobRunLeased: &armadaevents.JobRunLeased{ RunId: run.Id(), + RunIndex: run.Index(), JobId: job.Id(), ExecutorId: run.Executor(), // NodeId here refers to the unique identifier of the node in an executor cluster, @@ -809,13 +834,63 @@ func AppendEventSequencesFromScheduledJobs(eventSequences []*armadaevents.EventS return eventSequences, nil } +// evaluateRetryPolicy returns whether the run should be retried, the +// human-readable reason, and a `decided` flag. `decided=false` means the +// engine did not run (no policy assigned, policy missing from cache, or no +// run-error yet) and the caller must fall through to legacy behaviour. +// `decided=true` is authoritative - the engine's verdict wins. +func (s *Scheduler) evaluateRetryPolicy( + ctx *armadacontext.Context, + job *jobdb.Job, + runError *armadaevents.Error, + queueRetryPolicies map[string]string, +) (shouldRetry bool, reason string, decided bool) { + // Gang retry is out of scope for this MVP: atomic gang restart needs + // per-gang failure aggregation and a synchronised run-index bump across + // all members. See notes/retry-policy/gang-retry.md. Until that lands, + // gang failures fall through to the legacy lease-return retry path. + if job.IsInGang() { + return false, "", false + } + + policyName := queueRetryPolicies[job.Queue()] + if policyName == "" { + return false, "", false + } + policy, ok := s.retryPolicyCache.Get(policyName) + if !ok { + ctx.Warnf("retry policy %q referenced by queue %q not found in cache; falling back to legacy behaviour", policyName, job.Queue()) + return false, "", false + } + if runError == nil { + // Rare race with the ingester; let the legacy path surface its + // "out of sync" error if applicable. + return false, "", false + } + + // Pass FailureCount for both the policy and global tallies: counting + // len(AllRuns()) would also include preempted-but-not-failed runs (the + // scheduling algo creates a fresh run on reschedule), burning global-cap + // budget without any actual retry attempt. + failureCount := job.FailureCount() + result := s.retryEngine.Evaluate(policy, runError, failureCount, uint(failureCount)) + ctx.Infof("retry decision for job %s queue=%s policy=%s: ShouldRetry=%v Reason=%q", + job.Id(), job.Queue(), policyName, result.ShouldRetry, result.Reason) + return result.ShouldRetry, result.Reason, true +} + // generateUpdateMessages generates EventSequences representing the state changes on updated jobs. // If there are no state changes then an empty slice will be returned. func (s *Scheduler) generateUpdateMessages(ctx *armadacontext.Context, txn *jobdb.Txn, updatedJobs []*jobdb.Job, jobRunErrors map[string]*armadaevents.Error) ([]*armadaevents.EventSequence, error) { + // Build a queue-name -> retry-policy-name map once per cycle so the + // per-job failure path can resolve a queue's policy in O(1). When the + // feature flag is off the map stays nil and lookups fall through. + queueRetryPolicies := s.buildQueueRetryPolicyMap(ctx) + // Generate any eventSequences that came out of synchronising the db state. var events []*armadaevents.EventSequence for _, job := range updatedJobs { - jobEvents, err := s.generateUpdateMessagesFromJob(ctx, job, jobRunErrors, txn) + jobEvents, err := s.generateUpdateMessagesFromJob(ctx, job, jobRunErrors, queueRetryPolicies, txn) if err != nil { return nil, err } @@ -826,9 +901,31 @@ func (s *Scheduler) generateUpdateMessages(ctx *armadacontext.Context, txn *jobd return events, nil } +// buildQueueRetryPolicyMap returns a map of queue-name -> retry-policy-name. +// Returns nil when the feature flag is off or the queue cache is unavailable; +// callers must treat a missing entry as "no policy" (nil-map lookups return +// the zero string, which the per-job path handles). +func (s *Scheduler) buildQueueRetryPolicyMap(ctx *armadacontext.Context) map[string]string { + if !s.retryPolicyConfig.Enabled { + return nil + } + queues, err := s.queueCache.GetAll(ctx) + if err != nil { + ctx.Warnf("retry policy lookup: queue cache unavailable, falling back to legacy behaviour: %v", err) + return nil + } + m := make(map[string]string, len(queues)) + for _, q := range queues { + if q.RetryPolicy != "" { + m[q.Name] = q.RetryPolicy + } + } + return m +} + // generateUpdateMessages generates an EventSequence representing the state changes for a single job. // If there are no state changes it returns nil. -func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, job *jobdb.Job, jobRunErrors map[string]*armadaevents.Error, txn *jobdb.Txn) (*armadaevents.EventSequence, error) { +func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, job *jobdb.Job, jobRunErrors map[string]*armadaevents.Error, queueRetryPolicies map[string]string, txn *jobdb.Txn) (*armadaevents.EventSequence, error) { var events []*armadaevents.EventSequence_Event // Is the job already in a terminal state? If so then don't send any more messages @@ -939,8 +1036,29 @@ func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, jo } else if lastRun.Failed() && !job.Queued() { failFast := job.Annotations()[constants.FailFastAnnotation] == "true" requeueJob := !failFast && lastRun.Returned() && job.NumAttempts() < s.maxAttemptedRuns + retryDecisionReason := "" + policyEngineDecided := false + runError := jobRunErrors[lastRun.Id()] + + // When the engine returns decided=true its verdict overrides the + // legacy maxAttemptedRuns logic and suppresses the legacy + // "Maximum number of attempts ..." message. With the flag off, + // no policy assigned, or the named policy missing, behaviour is + // unchanged. + if !failFast && s.retryPolicyConfig.Enabled { + if shouldRetry, reason, decided := s.evaluateRetryPolicy(ctx, job, runError, queueRetryPolicies); decided { + requeueJob = shouldRetry + retryDecisionReason = reason + policyEngineDecided = true + } + } - if requeueJob && lastRun.RunAttempted() { + // Anti-affinity is a legacy LeaseReturned mechanism: if a node + // misbehaves, retry elsewhere. Engine-driven retries are + // semantic (e.g. exit-code 42); pinning the job off the failing + // node would defeat single-node dev clusters and policies that + // target transient app errors. Skip it when the engine decided. + if requeueJob && !policyEngineDecided && lastRun.RunAttempted() { jobWithAntiAffinity, schedulable, err := s.addNodeAntiAffinitiesForAttemptedRunsIfSchedulable(ctx, job) if err != nil { return nil, errors.Errorf("unable to set node anti-affinity for job %s because %s", job.Id(), err) @@ -955,6 +1073,30 @@ func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, jo } if requeueJob { + // On policy-engine retry, emit a non-terminal JobErrors so + // the api stream surfaces an intermediate failure with + // retryable=true. Only the engine path emits this: the + // legacy lease-return retry predates the signal and + // changing it would alter the event contract for existing + // operators. + if policyEngineDecided && runError != nil { + retryError := &armadaevents.Error{ + Terminal: false, + Reason: runError.Reason, + FailureCategory: runError.FailureCategory, + FailureSubcategory: runError.FailureSubcategory, + } + events = append(events, &armadaevents.EventSequence_Event{ + Created: s.now(), + Event: &armadaevents.EventSequence_Event_JobErrors{ + JobErrors: &armadaevents.JobErrors{ + JobId: job.Id(), + Errors: []*armadaevents.Error{retryError}, + }, + }, + }) + } + job = job.WithQueued(true) job = job.WithQueuedVersion(job.QueuedVersion() + 1) @@ -971,7 +1113,6 @@ func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, jo events = append(events, requeueJobEvent) } else { - runError := jobRunErrors[lastRun.Id()] if runError == nil { return nil, errors.Errorf( "no run error found for run %s (job id = %s), this must mean we're out of sync with the database", @@ -980,7 +1121,24 @@ func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, jo } job = job.WithFailed(true).WithQueued(false) - if lastRun.Returned() { + if policyEngineDecided { + // Wrap the engine reason (e.g. "policy retry limit + // exceeded (3/3)") in MaxRunsExceeded to reuse the + // existing terminal-failure path. Preserve + // FailureCategory/FailureSubcategory so dashboards and + // alerts keyed on them keep working for policy-terminated + // jobs. + runError = &armadaevents.Error{ + Terminal: true, + FailureCategory: runError.GetFailureCategory(), + FailureSubcategory: runError.GetFailureSubcategory(), + Reason: &armadaevents.Error_MaxRunsExceeded{ + MaxRunsExceeded: &armadaevents.MaxRunsExceeded{ + Message: fmt.Sprintf("Retry policy: %s", retryDecisionReason), + }, + }, + } + } else if lastRun.Returned() { errorMessage := fmt.Sprintf("Maximum number of attempts (%d) reached - this job will no longer be retried", s.maxAttemptedRuns) if job.NumAttempts() < s.maxAttemptedRuns { errorMessage = fmt.Sprintf("Job was attempted %d times, and has been tried once on all nodes it can run on - this job will no longer be retried", job.NumAttempts()) diff --git a/internal/scheduler/scheduler_test.go b/internal/scheduler/scheduler_test.go index d20da0966f1..b6abea99faa 100644 --- a/internal/scheduler/scheduler_test.go +++ b/internal/scheduler/scheduler_test.go @@ -24,6 +24,7 @@ import ( protoutil "github.com/armadaproject/armada/internal/common/proto" "github.com/armadaproject/armada/internal/common/pulsarutils" "github.com/armadaproject/armada/internal/common/util" + schedulerconfig "github.com/armadaproject/armada/internal/scheduler/configuration" "github.com/armadaproject/armada/internal/scheduler/database" schedulerdb "github.com/armadaproject/armada/internal/scheduler/database" "github.com/armadaproject/armada/internal/scheduler/internaltypes" @@ -32,6 +33,7 @@ import ( "github.com/armadaproject/armada/internal/scheduler/leader" "github.com/armadaproject/armada/internal/scheduler/metrics" "github.com/armadaproject/armada/internal/scheduler/pricing" + "github.com/armadaproject/armada/internal/scheduler/retry" "github.com/armadaproject/armada/internal/scheduler/schedulerobjects" "github.com/armadaproject/armada/internal/scheduler/scheduling" schedulercontext "github.com/armadaproject/armada/internal/scheduler/scheduling/context" @@ -1027,6 +1029,8 @@ func TestScheduler_TestCycle(t *testing.T) { pricing.NoopBidPriceProvider{}, []string{}, queueCache, + schedulerconfig.RetryPolicyConfig{}, + retry.NoopPolicyCache{}, ) require.NoError(t, err) sched.EnableAssertions() @@ -1232,6 +1236,8 @@ func TestRun(t *testing.T) { pricing.NoopBidPriceProvider{}, []string{}, &testQueueCache{}, + schedulerconfig.RetryPolicyConfig{}, + retry.NoopPolicyCache{}, ) require.NoError(t, err) sched.EnableAssertions() @@ -1424,6 +1430,8 @@ func TestJobPriceUpdates(t *testing.T) { priceProvider, tc.marketDrivenPools, &testQueueCache{}, + schedulerconfig.RetryPolicyConfig{}, + retry.NoopPolicyCache{}, ) require.NoError(t, err) @@ -1613,6 +1621,8 @@ func TestScheduler_TestSyncInitialState(t *testing.T) { pricing.NoopBidPriceProvider{}, []string{}, &testQueueCache{}, + schedulerconfig.RetryPolicyConfig{}, + retry.NoopPolicyCache{}, ) require.NoError(t, err) sched.EnableAssertions() @@ -1828,6 +1838,8 @@ func TestScheduler_TestSyncState(t *testing.T) { pricing.NoopBidPriceProvider{}, []string{}, &testQueueCache{}, + schedulerconfig.RetryPolicyConfig{}, + retry.NoopPolicyCache{}, ) require.NoError(t, err) sched.EnableAssertions() @@ -3088,6 +3100,8 @@ func TestCycleConsistency(t *testing.T) { pricing.NoopBidPriceProvider{}, []string{}, &testQueueCache{}, + schedulerconfig.RetryPolicyConfig{}, + retry.NoopPolicyCache{}, ) require.NoError(t, err) scheduler.clock = testClock diff --git a/internal/scheduler/schedulerapp.go b/internal/scheduler/schedulerapp.go index f2da6784f1f..98a13618d3e 100644 --- a/internal/scheduler/schedulerapp.go +++ b/internal/scheduler/schedulerapp.go @@ -45,6 +45,7 @@ import ( "github.com/armadaproject/armada/internal/scheduler/priorityoverride" "github.com/armadaproject/armada/internal/scheduler/queue" "github.com/armadaproject/armada/internal/scheduler/reports" + "github.com/armadaproject/armada/internal/scheduler/retry" "github.com/armadaproject/armada/internal/scheduler/scheduling" "github.com/armadaproject/armada/pkg/api" "github.com/armadaproject/armada/pkg/api/schedulerobjects" @@ -138,6 +139,28 @@ func Run(config schedulerconfig.Configuration) error { } services = append(services, func() error { return queueCache.Run(ctx) }) + // //////////////////////////////////////////////////////////////////////// + // Retry Policy Cache + // //////////////////////////////////////////////////////////////////////// + // We always wire the policy cache, but only run the refresher when the + // retry policy feature is enabled. With the flag off the scheduler + // receives a NoopPolicyCache so the failure path skips engine evaluation + // entirely and behaviour is byte-identical to the pre-feature build. + var retryPolicyCache retry.PolicyCache = retry.NoopPolicyCache{} + if config.Scheduling.RetryPolicy.Enabled { + retryPolicyClient := api.NewRetryPolicyServiceClient(conn) + // Reuse the queue refresh cadence; both caches answer scheduler + // failure-handling questions and stale data has the same impact. + apiCache := retry.NewApiPolicyCache(retryPolicyClient, config.QueueRefreshPeriod) + retryPolicyInitTimeout, cancelRetry := armadacontext.WithTimeout(ctx, time.Second*30) + defer cancelRetry() + if err := apiCache.Initialise(retryPolicyInitTimeout); err != nil { + ctx.Errorf("error initialising retry policy cache - %v", err) + } + services = append(services, func() error { return apiCache.Run(ctx) }) + retryPolicyCache = apiCache + } + // //////////////////////////////////////////////////////////////////////// // Priority override // //////////////////////////////////////////////////////////////////////// @@ -402,6 +425,8 @@ func Run(config schedulerconfig.Configuration) error { bidPriceProvider, marketDrivenPools, queueCache, + config.Scheduling.RetryPolicy, + retryPolicyCache, ) if err != nil { return errors.WithMessage(err, "error creating scheduler") From b02a0cee4d63ea5275a283805bf1bda5dca4a7ff Mon Sep 17 00:00:00 2001 From: Dejan Zele Pejchev Date: Fri, 8 May 2026 16:48:51 +0200 Subject: [PATCH 5/5] Add retry policy testsuite case Signed-off-by: Dejan Zele Pejchev --- developer/config/insecure-armada.yaml | 7 +++ .../testsuite/eventwatcher/eventwatcher.go | 11 +++- internal/testsuite/eventwatcher/validators.go | 19 +++--- magefiles/ci.go | 49 ++++++++++++++- .../testcases/retries/single_pod_retry.yaml | 62 +++++++++++++++++++ 5 files changed, 135 insertions(+), 13 deletions(-) create mode 100644 testsuite/testcases/retries/single_pod_retry.yaml diff --git a/developer/config/insecure-armada.yaml b/developer/config/insecure-armada.yaml index 586176ad988..0bd16910be4 100644 --- a/developer/config/insecure-armada.yaml +++ b/developer/config/insecure-armada.yaml @@ -13,3 +13,10 @@ auth: watch_all_events: ["everyone"] execute_jobs: ["everyone"] update_executor_settings: ["everyone"] + create_retry_policy: ["everyone"] + update_retry_policy: ["everyone"] + delete_retry_policy: ["everyone"] +scheduling: + retryPolicy: + enabled: true + globalMaxRetries: 5 diff --git a/internal/testsuite/eventwatcher/eventwatcher.go b/internal/testsuite/eventwatcher/eventwatcher.go index 2062702cc31..33d57ddd06b 100644 --- a/internal/testsuite/eventwatcher/eventwatcher.go +++ b/internal/testsuite/eventwatcher/eventwatcher.go @@ -224,9 +224,11 @@ func assertEventErrorString(expected []*api.EventMessage, indexByJobId map[strin } func isTerminalEvent(msg *api.EventMessage) bool { - switch msg.Events.(type) { + switch e := msg.Events.(type) { case *api.EventMessage_Failed: - return true + // Retryable failures are intermediate; the scheduler will re-lease + // the job, so keep consuming until a truly terminal event arrives. + return !e.Failed.GetRetryable() case *api.EventMessage_Succeeded: return true case *api.EventMessage_Cancelled: @@ -271,6 +273,11 @@ func ErrorOnNoActiveJobs(parent context.Context, C chan *api.EventMessage, jobId numActive-- } } else if e := msg.GetFailed(); e != nil { + // Retryable failures are intermediate; skip them so the + // watcher stays alive past the retry boundary. + if e.GetRetryable() { + continue + } // Failed may come after Preempted for preempted jobs. // Only count as exited once. if _, ok := exitedByJobId[e.JobId]; !ok { diff --git a/internal/testsuite/eventwatcher/validators.go b/internal/testsuite/eventwatcher/validators.go index 9dfedaeee64..7dbb0a515a4 100644 --- a/internal/testsuite/eventwatcher/validators.go +++ b/internal/testsuite/eventwatcher/validators.go @@ -36,18 +36,17 @@ func assertEventFailed(expected *api.EventMessage_Failed, actual *api.EventMessa } } - if expected.Failed.GetFailureCategory() != "" { - if expected.Failed.GetFailureCategory() != actual.Failed.GetFailureCategory() { - return errors.Errorf("expected failure_category %q but got %q", - expected.Failed.GetFailureCategory(), actual.Failed.GetFailureCategory()) - } + if cat := expected.Failed.GetFailureCategory(); cat != "" && cat != actual.Failed.GetFailureCategory() { + return errors.Errorf("expected failure_category %q but got %q", cat, actual.Failed.GetFailureCategory()) } - if expected.Failed.GetFailureSubcategory() != "" { - if expected.Failed.GetFailureSubcategory() != actual.Failed.GetFailureSubcategory() { - return errors.Errorf("expected failure_subcategory %q but got %q", - expected.Failed.GetFailureSubcategory(), actual.Failed.GetFailureSubcategory()) - } + if sub := expected.Failed.GetFailureSubcategory(); sub != "" && sub != actual.Failed.GetFailureSubcategory() { + return errors.Errorf("expected failure_subcategory %q but got %q", sub, actual.Failed.GetFailureSubcategory()) + } + + if expected.Failed.GetRetryable() != actual.Failed.GetRetryable() { + return errors.Errorf("expected retryable=%t but got retryable=%t", + expected.Failed.GetRetryable(), actual.Failed.GetRetryable()) } return nil diff --git a/magefiles/ci.go b/magefiles/ci.go index 162931f9f81..a1439677a47 100644 --- a/magefiles/ci.go +++ b/magefiles/ci.go @@ -22,6 +22,52 @@ func createQueue() error { return nil } +// createRetryPolicyAndQueue creates the retry policy and queue used by the +// retries testsuite cases. The policy retries on AppError up to 2 times, +// giving 3 total attempts before terminal failure. +func createRetryPolicyAndQueue() error { + policyPath, err := writeRetryPolicyFile() + if err != nil { + return fmt.Errorf("failed to stage retry policy file: %w", err) + } + defer os.Remove(policyPath) + + out, err := runArmadaCtl("create", "retry-policy", "-f", policyPath) + if err != nil && !strings.Contains(out, "already exists") { + fmt.Println(out) + return err + } + + out, err = runArmadaCtl("create", "queue", "e2e-retry-queue", "--retry-policy", "e2e-retry-policy") + if err != nil && !strings.Contains(out, "already exists") { + fmt.Println(out) + return err + } + + return nil +} + +func writeRetryPolicyFile() (string, error) { + const policy = `apiVersion: armadaproject.io/v1beta1 +kind: RetryPolicy +name: e2e-retry-policy +retryLimit: 2 +defaultAction: Fail +rules: + - action: Retry + onConditions: ["AppError"] +` + f, err := os.CreateTemp("", "retry-policy-*.yaml") + if err != nil { + return "", err + } + defer f.Close() + if _, err := f.WriteString(policy); err != nil { + return "", err + } + return f.Name(), nil +} + // Build images, spin up a test environment, and run the integration tests against it. func TestSuite() error { mg.Deps(CheckForArmadaRunning) @@ -36,7 +82,7 @@ func TestSuite() error { timeTaken := time.Now() out, err2 := goOutput("run", "cmd/testsuite/main.go", "test", - "--tests", "testsuite/testcases/basic/*,testsuite/testcases/categorization/*", + "--tests", "testsuite/testcases/basic/*,testsuite/testcases/categorization/*,testsuite/testcases/retries/*", "--junit", "junit.xml", "--config", "e2e/config/armadactl_config.yaml", ) @@ -57,6 +103,7 @@ func CheckForArmadaRunning() error { // TODO Make a good check to confirm the system is ready, such as seeing armadactl get executors return a value mg.Deps(CheckSchedulerReady) mg.Deps(createQueue) + mg.Deps(createRetryPolicyAndQueue) // Set high to take compile time into account timeout := time.After(2 * time.Minute) diff --git a/testsuite/testcases/retries/single_pod_retry.yaml b/testsuite/testcases/retries/single_pod_retry.yaml new file mode 100644 index 00000000000..3c2eba672f3 --- /dev/null +++ b/testsuite/testcases/retries/single_pod_retry.yaml @@ -0,0 +1,62 @@ +numBatches: 1 +batchSize: 1 +queue: e2e-retry-queue +jobs: + - priority: 0 + namespace: default + podSpec: + terminationGracePeriodSeconds: 0 + restartPolicy: Never + containers: + - name: fail-then-succeed + imagePullPolicy: IfNotPresent + image: alpine:3.20.0 + command: ["sh", "-c"] + args: + # The pod reads the run-index label set by the executor (commit 3) + # via the downward API. Run 0 exits 1 to trigger the retry policy; + # run 1 exits 0. A succeeded terminal event is therefore only + # possible if (a) the engine decided to retry, (b) the run-index + # was correctly incremented, (c) the new pod name was unique, and + # (d) the label was set on the retry pod. + - | + run_index=$(cat /podinfo/run_index) + echo "run_index=$run_index" + if [ "$run_index" = "0" ]; then + echo "first attempt: failing intentionally to trigger retry" + exit 1 + fi + echo "retry attempt: succeeding" + exit 0 + volumeMounts: + - name: podinfo + mountPath: /podinfo + resources: + limits: + memory: 25Mi + cpu: 100m + requests: + memory: 25Mi + cpu: 100m + volumes: + - name: podinfo + downwardAPI: + items: + - path: run_index + fieldRef: + fieldPath: "metadata.labels['armada_job_run_index']" +--- +timeout: "300s" +# `failed: retryable: true` proves the scheduler emitted a non-terminal +# JobErrors event (translated to JobFailedEvent.retryable=true) because the +# retry-policy engine matched a Retry rule. The watcher does not treat a +# retryable failure as terminal, so it keeps consuming events until the +# retried pod succeeds. `succeeded` is unreachable unless the second pod +# observed run_index>0 via the downward API, which only happens if the +# executor incremented the index for the new lease. +expectedEvents: + - submitted: + - leased: + - failed: + retryable: true + - succeeded: