diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ca1f4c10597..bc202e316c7 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -23,9 +23,9 @@ jobs:
cache: yarn
cache-dependency-path: ./internal/lookoutui/yarn.lock
- - name: Install Dependencies And Run Unit Tests
+ - name: Install Dependencies, Check Types And Run Unit Tests
run: |
- yarn install --frozen-lockfile && yarn openapi && CI=true yarn test --reporter=junit
+ yarn install --frozen-lockfile && yarn openapi && yarn typecheck && CI=true yarn test --reporter=junit
working-directory: ./internal/lookoutui
- name: Publish JUnit Report
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 971a76269d8..cb7907aa6e0 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -68,18 +68,18 @@ builds:
goarch:
- amd64
- env: [CGO_ENABLED=0]
- id: lookoutv2
- binary: lookoutv2
- main: ./cmd/lookoutv2/main.go
+ id: lookout
+ binary: lookout
+ main: ./cmd/lookout/main.go
mod_timestamp: '{{ .CommitTimestamp }}'
goos:
- linux
goarch:
- amd64
- env: [CGO_ENABLED=0]
- id: lookoutingesterv2
- binary: lookoutingesterv2
- main: ./cmd/lookoutingesterv2/main.go
+ id: lookoutingester
+ binary: lookoutingester
+ main: ./cmd/lookoutingester/main.go
mod_timestamp: '{{ .CommitTimestamp }}'
goos:
- linux
@@ -215,12 +215,12 @@ dockers:
- "{{ .Env.DOCKER_REPO }}armada-lookout-bundle:{{ .Version }}"
build_flag_templates: *BUILD_FLAG_TEMPLATES
ids:
- - lookoutv2
- - lookoutingesterv2
+ - lookout
+ - lookoutingester
extra_files:
- config/logging.yaml
- - config/lookoutv2/config.yaml
- - config/lookoutingesterv2/config.yaml
+ - config/lookout/config.yaml
+ - config/lookoutingester/config.yaml
- internal/lookoutui
- pkg/api/api.swagger.json
- pkg/api/binoculars/api.swagger.json
@@ -243,8 +243,8 @@ dockers:
- armadactl
- scheduler
- scheduleringester
- - lookoutv2
- - lookoutingesterv2
+ - lookout
+ - lookoutingester
- fakeexecutor
extra_files:
- config/logging.yaml
@@ -254,8 +254,8 @@ dockers:
- config/eventingester/config.yaml
- config/scheduler/config.yaml
- config/scheduleringester/config.yaml
- - config/lookoutv2/config.yaml
- - config/lookoutingesterv2/config.yaml
+ - config/lookout/config.yaml
+ - config/lookoutingester/config.yaml
- internal/lookoutui
- pkg/api/api.swagger.json
- pkg/api/binoculars/api.swagger.json
@@ -331,41 +331,45 @@ dockers:
- testsuite
dockerfile: ./build/testsuite/Dockerfile
- - id: lookoutingesterv2
+ - id: lookoutingester
use: buildx
goos: linux
goarch: amd64
image_templates:
- "{{ .Env.DOCKER_REPO }}armada-lookout-ingester-v2:latest"
- "{{ .Env.DOCKER_REPO }}armada-lookout-ingester-v2:{{ .Version }}"
+ - "{{ .Env.DOCKER_REPO }}armada-lookout-ingester:latest"
+ - "{{ .Env.DOCKER_REPO }}armada-lookout-ingester:{{ .Version }}"
build_flag_templates: *BUILD_FLAG_TEMPLATES
ids:
- - lookoutingesterv2
+ - lookoutingester
extra_files:
- - config/lookoutingesterv2/config.yaml
+ - config/lookoutingester/config.yaml
- config/logging.yaml
- dockerfile: ./build/lookoutingesterv2/Dockerfile
+ dockerfile: ./build/lookoutingester/Dockerfile
- - id: lookoutv2
+ - id: lookout
use: buildx
goos: linux
goarch: amd64
image_templates:
- "{{ .Env.DOCKER_REPO }}armada-lookout-v2:latest"
- "{{ .Env.DOCKER_REPO }}armada-lookout-v2:{{ .Version }}"
+ - "{{ .Env.DOCKER_REPO }}armada-lookout:latest"
+ - "{{ .Env.DOCKER_REPO }}armada-lookout:{{ .Version }}"
build_flag_templates: *BUILD_FLAG_TEMPLATES
ids:
- - lookoutv2
- - lookoutingesterv2
+ - lookout
+ - lookoutingester
extra_files:
- internal/lookoutui
- pkg/api/api.swagger.json
- pkg/api/binoculars/api.swagger.json
- pkg/api/schedulerobjects/api.swagger.json
- - config/lookoutv2/config.yaml
- - config/lookoutingesterv2/config.yaml
+ - config/lookout/config.yaml
+ - config/lookoutingester/config.yaml
- config/logging.yaml
- dockerfile: ./build/lookoutv2/Dockerfile
+ dockerfile: ./build/lookout/Dockerfile
- id: eventingester
use: buildx
@@ -500,12 +504,16 @@ release:
#### Armada Executor
- `docker pull {{ .Env.DOCKER_REPO }}armada-executor:{{ .Version }}`
- `docker pull {{ .Env.DOCKER_REPO }}armada-executor:latest`
- #### Armada Lookout V2
+ #### Armada Lookout
- `docker pull {{ .Env.DOCKER_REPO }}armada-lookout-v2:{{ .Version }}`
- `docker pull {{ .Env.DOCKER_REPO }}armada-lookout-v2:latest`
- #### Armada Lookout Ingester V2
+ - `docker pull {{ .Env.DOCKER_REPO }}armada-lookout:{{ .Version }}`
+ - `docker pull {{ .Env.DOCKER_REPO }}armada-lookout:latest`
+ #### Armada Lookout Ingester
- `docker pull {{ .Env.DOCKER_REPO }}armada-lookout-ingester-v2:{{ .Version }}`
- `docker pull {{ .Env.DOCKER_REPO }}armada-lookout-ingester-v2:latest`
+ - `docker pull {{ .Env.DOCKER_REPO }}armada-lookout-ingester:{{ .Version }}`
+ - `docker pull {{ .Env.DOCKER_REPO }}armada-lookout-ingester:latest`
#### Armada Event Ingester
- `docker pull {{ .Env.DOCKER_REPO }}armada-event-ingester:{{ .Version }}`
- `docker pull {{ .Env.DOCKER_REPO }}armada-event-ingester:latest`
diff --git a/.mergify.yml b/.mergify.yml
index e4c1d8077fc..998004cb4aa 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -9,6 +9,6 @@ pull_request_rules:
- "#approved-reviews-by>=2"
- and:
- "#approved-reviews-by>=1"
- - "author~=^(d80tb7|dave[-]gantenbein|dejanzele|eleanorpratt|geaere|JamesMurkin|mauriceyap|masipauskas|MustafaI|zuqq|richscott|robertdavidsmith|samclark|suprjinx)"
+ - "author~=^(d80tb7|dave[-]gantenbein|dejanzele|eleanorpratt|geaere|JamesMurkin|mauriceyap|masipauskas|MustafaI|zuqq|richscott|robertdavidsmith|samclark|suprjinx|EnricoMi)$"
title:
- Two are checks required.
+ Two approvals required, or one if author is a maintainer.
diff --git a/.run/Armada Infrastructure Services.run.xml b/.run/Armada Infrastructure Services.run.xml
index ef723ce1a95..e0bee3f7019 100644
--- a/.run/Armada Infrastructure Services.run.xml
+++ b/.run/Armada Infrastructure Services.run.xml
@@ -5,15 +5,13 @@
-
-
-
+
-
+
\ No newline at end of file
diff --git a/.run/Armada.run.xml b/.run/Armada.run.xml
index 766791134b7..19c31836e6a 100644
--- a/.run/Armada.run.xml
+++ b/.run/Armada.run.xml
@@ -2,11 +2,11 @@
-
-
+
+
-
\ No newline at end of file
+
diff --git a/.run/Lookout Ingester V2.run.xml b/.run/Lookout Ingester.run.xml
similarity index 70%
rename from .run/Lookout Ingester V2.run.xml
rename to .run/Lookout Ingester.run.xml
index f522609ffb0..cc247436395 100644
--- a/.run/Lookout Ingester V2.run.xml
+++ b/.run/Lookout Ingester.run.xml
@@ -1,5 +1,5 @@
-
+
@@ -10,9 +10,9 @@
-
+
-
+
diff --git a/.run/LookoutV2 UI.run.xml b/.run/Lookout UI.run.xml
similarity index 91%
rename from .run/LookoutV2 UI.run.xml
rename to .run/Lookout UI.run.xml
index 6f20d1d36ee..9615ea17300 100644
--- a/.run/LookoutV2 UI.run.xml
+++ b/.run/Lookout UI.run.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/.run/LookoutV2.run.xml b/.run/Lookout.run.xml
similarity index 78%
rename from .run/LookoutV2.run.xml
rename to .run/Lookout.run.xml
index a85ddf17726..6b389c175f4 100644
--- a/.run/LookoutV2.run.xml
+++ b/.run/Lookout.run.xml
@@ -1,5 +1,5 @@
-
+
@@ -11,9 +11,9 @@
-
+
-
+
diff --git a/.run/lookoutv2PostgresMigration.run.xml b/.run/lookoutPostgresMigration.run.xml
similarity index 74%
rename from .run/lookoutv2PostgresMigration.run.xml
rename to .run/lookoutPostgresMigration.run.xml
index b8f4290c280..f002aad7b03 100644
--- a/.run/lookoutv2PostgresMigration.run.xml
+++ b/.run/lookoutPostgresMigration.run.xml
@@ -1,5 +1,5 @@
-
+
@@ -10,9 +10,9 @@
-
+
-
+
diff --git a/build/bundles/full/Dockerfile b/build/bundles/full/Dockerfile
index 6b44751c4a6..a7dde81625a 100644
--- a/build/bundles/full/Dockerfile
+++ b/build/bundles/full/Dockerfile
@@ -23,7 +23,7 @@ RUN addgroup -S -g 2000 armada && adduser -S -u 1000 armada -G armada
USER armada
COPY --from=NODE /lookoutui/build/ /app/internal/lookoutui/build
-COPY server executor binoculars eventingester lookoutingesterv2 lookoutv2 scheduler scheduleringester armadactl /app/
+COPY server executor binoculars eventingester lookoutingester lookout scheduler scheduleringester armadactl /app/
COPY config/ /app/config/
WORKDIR /app
diff --git a/build/bundles/lookout/Dockerfile b/build/bundles/lookout/Dockerfile
index 5d5354bafc9..30d025a7a80 100644
--- a/build/bundles/lookout/Dockerfile
+++ b/build/bundles/lookout/Dockerfile
@@ -11,10 +11,10 @@ USER armada
# Logging (shared between both components)
COPY config/logging.yaml /app/config/logging.yaml
-COPY config/lookoutingesterv2/config.yaml /app/config/lookoutingesterv2/config.yaml
+COPY config/lookoutingester/config.yaml /app/config/lookoutingester/config.yaml
-COPY config/lookoutv2/config.yaml /app/config/lookoutv2/config.yaml
+COPY config/lookout/config.yaml /app/config/lookout/config.yaml
-COPY lookoutingesterv2 lookoutv2 /app/
+COPY lookoutingester lookout /app/
WORKDIR /app
diff --git a/build/lookoutv2/Dockerfile b/build/lookout/Dockerfile
similarity index 73%
rename from build/lookoutv2/Dockerfile
rename to build/lookout/Dockerfile
index dd8020a36e6..4dec30b121b 100644
--- a/build/lookoutv2/Dockerfile
+++ b/build/lookout/Dockerfile
@@ -18,15 +18,15 @@ RUN yarn build
FROM ${BASE_IMAGE}
RUN addgroup -S -g 2000 armada && adduser -S -u 1000 armada -G armada
-LABEL org.opencontainers.image.title=lookoutv2
-LABEL org.opencontainers.image.description="Lookout V2"
-LABEL org.opencontainers.image.url=https://hub.docker.com/r/gresearch/lookoutv2
+LABEL org.opencontainers.image.title=lookout
+LABEL org.opencontainers.image.description="Lookout"
+LABEL org.opencontainers.image.url=https://hub.docker.com/r/gresearch/lookout
USER armada
COPY --from=NODE /lookoutui/build/ /app/internal/lookoutui/build
-COPY lookoutv2 /app/
-COPY config/lookoutv2/config.yaml /app/config/lookoutv2/config.yaml
-COPY lookoutingesterv2 /app/
-COPY config/lookoutingesterv2/ /app/config/lookoutingesterv2
+COPY lookout /app/
+COPY config/lookout/config.yaml /app/config/lookout/config.yaml
+COPY lookoutingester /app/
+COPY config/lookoutingester/ /app/config/lookoutingester
COPY config/logging.yaml /app/config/logging.yaml
WORKDIR /app
-ENTRYPOINT ["./lookoutv2"]
+ENTRYPOINT ["./lookout"]
diff --git a/build/lookoutingester/Dockerfile b/build/lookoutingester/Dockerfile
new file mode 100644
index 00000000000..54b0ea98bed
--- /dev/null
+++ b/build/lookoutingester/Dockerfile
@@ -0,0 +1,17 @@
+ARG BASE_IMAGE=alpine:3.21.0
+
+FROM ${BASE_IMAGE}
+LABEL org.opencontainers.image.title=lookoutingester
+LABEL org.opencontainers.image.description="Lookout Ingester"
+LABEL org.opencontainers.image.url=https://hub.docker.com/r/gresearch/lookoutingester
+
+RUN addgroup -S -g 2000 armada && adduser -S -u 1000 armada -G armada
+USER armada
+
+COPY lookoutingester /app/
+COPY config/lookoutingester/config.yaml /app/config/lookoutingester/config.yaml
+COPY config/logging.yaml /app/config/logging.yaml
+
+WORKDIR /app
+
+ENTRYPOINT ["./lookoutingester"]
diff --git a/build/lookoutingesterv2/Dockerfile b/build/lookoutingesterv2/Dockerfile
deleted file mode 100644
index e5c70002b22..00000000000
--- a/build/lookoutingesterv2/Dockerfile
+++ /dev/null
@@ -1,17 +0,0 @@
-ARG BASE_IMAGE=alpine:3.21.0
-
-FROM ${BASE_IMAGE}
-LABEL org.opencontainers.image.title=lookoutingesterv2
-LABEL org.opencontainers.image.description="Lookout Ingester V2"
-LABEL org.opencontainers.image.url=https://hub.docker.com/r/gresearch/lookoutingesterv2
-
-RUN addgroup -S -g 2000 armada && adduser -S -u 1000 armada -G armada
-USER armada
-
-COPY lookoutingesterv2 /app/
-COPY config/lookoutingesterv2/config.yaml /app/config/lookoutingesterv2/config.yaml
-COPY config/logging.yaml /app/config/logging.yaml
-
-WORKDIR /app
-
-ENTRYPOINT ["./lookoutingesterv2"]
diff --git a/cmd/lookout/dbloadtester/config.yaml b/cmd/lookout/dbloadtester/config.yaml
new file mode 100644
index 00000000000..783e2acd794
--- /dev/null
+++ b/cmd/lookout/dbloadtester/config.yaml
@@ -0,0 +1,10 @@
+#sample config
+---
+queues:
+ - "queue1"
+ids:
+ - "01JD2FF8TTJAXCNFB0F91053ZD"
+jobsets:
+ - "jobset1"
+queueCounts:
+ queue1: 1000000
diff --git a/cmd/lookout/dbloadtester/main.go b/cmd/lookout/dbloadtester/main.go
new file mode 100644
index 00000000000..f1bb0d1d731
--- /dev/null
+++ b/cmd/lookout/dbloadtester/main.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+
+ "github.com/spf13/pflag"
+ "github.com/spf13/viper"
+
+ "github.com/armadaproject/armada/internal/common"
+ "github.com/armadaproject/armada/internal/common/armadacontext"
+ log "github.com/armadaproject/armada/internal/common/logging"
+ "github.com/armadaproject/armada/internal/common/profiling"
+ "github.com/armadaproject/armada/internal/lookout/configuration"
+ "github.com/armadaproject/armada/internal/lookout/dbloadtester"
+)
+
+const (
+ customConfigLocation string = "config"
+ customParamsLocation string = "params"
+)
+
+func init() {
+ pflag.StringSlice(
+ customConfigLocation,
+ []string{},
+ "path to the configuration for the Lookout under test",
+ )
+ pflag.StringSlice(
+ customParamsLocation,
+ []string{},
+ "parameters to the load test, defining the shape of the load",
+ )
+ pflag.Parse()
+}
+
+func makeContext() (*armadacontext.Context, func()) {
+ ctx := armadacontext.Background()
+ ctx, cancel := armadacontext.WithCancel(ctx)
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt, syscall.SIGTERM)
+
+ go func() {
+ select {
+ case <-c:
+ cancel()
+ case <-ctx.Done():
+ }
+ }()
+
+ return ctx, func() {
+ signal.Stop(c)
+ cancel()
+ }
+}
+
+func main() {
+ common.BindCommandlineArguments()
+
+ var config configuration.LookoutConfig
+ userSpecifiedConfigs := viper.GetStringSlice(customConfigLocation)
+ common.LoadConfig(&config, "./config/lookout", userSpecifiedConfigs)
+
+ var args dbloadtester.ReadTestConfig
+ argsInput := viper.GetStringSlice(customParamsLocation)
+ common.LoadConfig(&args, "./cmd/lookout/dbloadtester", argsInput)
+
+ // Expose profiling endpoints if enabled.
+ err := profiling.SetupPprof(config.Profiling, armadacontext.Background(), nil)
+ if err != nil {
+ log.Fatalf("Pprof setup failed, exiting, %v", err)
+ }
+
+ ctx, cleanup := makeContext()
+ defer cleanup()
+
+ results, err := dbloadtester.DoQueries(config, args, ctx)
+ if err != nil {
+ log.Fatalf("error running queries, exiting, %v", err)
+ }
+
+ log.Infof("results: \n%v", results)
+}
diff --git a/cmd/lookoutv2/main.go b/cmd/lookout/main.go
similarity index 87%
rename from cmd/lookoutv2/main.go
rename to cmd/lookout/main.go
index 584aac3edf3..abe70ff744b 100644
--- a/cmd/lookoutv2/main.go
+++ b/cmd/lookout/main.go
@@ -14,11 +14,11 @@ import (
"github.com/armadaproject/armada/internal/common/database"
log "github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/profiling"
- "github.com/armadaproject/armada/internal/lookoutv2"
- "github.com/armadaproject/armada/internal/lookoutv2/configuration"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/restapi"
- "github.com/armadaproject/armada/internal/lookoutv2/pruner"
- "github.com/armadaproject/armada/internal/lookoutv2/schema"
+ "github.com/armadaproject/armada/internal/lookout"
+ "github.com/armadaproject/armada/internal/lookout/configuration"
+ "github.com/armadaproject/armada/internal/lookout/gen/restapi"
+ "github.com/armadaproject/armada/internal/lookout/pruner"
+ "github.com/armadaproject/armada/internal/lookout/schema"
armada_config "github.com/armadaproject/armada/internal/server/configuration"
)
@@ -60,7 +60,7 @@ func makeContext() (*armadacontext.Context, func()) {
}
}
-func migrate(ctx *armadacontext.Context, config configuration.LookoutV2Config) {
+func migrate(ctx *armadacontext.Context, config configuration.LookoutConfig) {
db, err := database.OpenPgxPool(config.Postgres)
if err != nil {
panic(err)
@@ -77,7 +77,7 @@ func migrate(ctx *armadacontext.Context, config configuration.LookoutV2Config) {
}
}
-func prune(ctx *armadacontext.Context, config configuration.LookoutV2Config) {
+func prune(ctx *armadacontext.Context, config configuration.LookoutConfig) {
var dbConfig armada_config.PostgresConfig
if config.PrunerConfig.Postgres.Connection != nil {
dbConfig = config.PrunerConfig.Postgres
@@ -120,9 +120,9 @@ func main() {
log.MustConfigureApplicationLogging()
common.BindCommandlineArguments()
- var config configuration.LookoutV2Config
+ var config configuration.LookoutConfig
userSpecifiedConfigs := viper.GetStringSlice(CustomConfigLocation)
- common.LoadConfig(&config, "./config/lookoutv2", userSpecifiedConfigs)
+ common.LoadConfig(&config, "./config/lookout", userSpecifiedConfigs)
// Expose profiling endpoints if enabled.
err := profiling.SetupPprof(config.Profiling, armadacontext.Background(), nil)
@@ -147,7 +147,7 @@ func main() {
restapi.UIConfig = config.UIConfig
- if err := lookoutv2.Serve(config); err != nil {
+ if err := lookout.Serve(config); err != nil {
log.Error(err.Error())
os.Exit(1)
}
diff --git a/cmd/lookoutingesterv2/dbloadtester/main.go b/cmd/lookoutingester/dbloadtester/main.go
similarity index 79%
rename from cmd/lookoutingesterv2/dbloadtester/main.go
rename to cmd/lookoutingester/dbloadtester/main.go
index 95e4b834673..9c14af6d497 100644
--- a/cmd/lookoutingesterv2/dbloadtester/main.go
+++ b/cmd/lookoutingester/dbloadtester/main.go
@@ -1,7 +1,6 @@
package main
import (
- "fmt"
"time"
"github.com/spf13/pflag"
@@ -11,15 +10,15 @@ import (
"github.com/armadaproject/armada/internal/common"
"github.com/armadaproject/armada/internal/common/app"
log "github.com/armadaproject/armada/internal/common/logging"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/configuration"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/dbloadtester"
+ "github.com/armadaproject/armada/internal/lookoutingester/configuration"
+ "github.com/armadaproject/armada/internal/lookoutingester/dbloadtester"
)
func init() {
pflag.StringSlice(
"lookoutIngesterConfig",
[]string{},
- "Fully qualified path to application configuration file (for multiple config files repeat this arg or separate paths with commas)",
+ "path to the configuration for the lookout ingester under test",
)
pflag.Parse()
}
@@ -48,16 +47,16 @@ func main() {
log.MustConfigureApplicationLogging()
common.BindCommandlineArguments()
- var config configuration.LookoutIngesterV2Configuration
+ var config configuration.LookoutIngesterConfiguration
userSpecifiedConfigs := viper.GetStringSlice("lookoutIngesterConfig")
- common.LoadConfig(&config, "./config/lookoutingesterv2", userSpecifiedConfigs)
+ common.LoadConfig(&config, "./config/lookoutingester", userSpecifiedConfigs)
loadtesterConfig := dbloadtester.Config{
TotalJobs: 500000,
TotalConcurrentJobs: 50000,
QueueSubmitBatchSize: 300,
QueueNames: []string{"queue1", "queue2", "queue3"},
- JobTemplateFile: "internal/lookoutingesterv2/dbloadtester/test_data.yaml",
+ JobTemplateFile: "internal/lookoutingester/dbloadtester/test_data.yaml",
}
loadtester := dbloadtester.Setup(
@@ -74,7 +73,7 @@ func main() {
if err != nil {
log.Warn("Failed to marshal lookout ingester config for report output")
}
- fmt.Printf(
+ log.Infof(
ReportTemplate,
time.Now().Format("2006-01-02"),
loadtesterConfig.TotalJobs,
diff --git a/cmd/lookoutingesterv2/main.go b/cmd/lookoutingester/main.go
similarity index 70%
rename from cmd/lookoutingesterv2/main.go
rename to cmd/lookoutingester/main.go
index 70be8d713f2..5f35380d8d8 100644
--- a/cmd/lookoutingesterv2/main.go
+++ b/cmd/lookoutingester/main.go
@@ -6,9 +6,9 @@ import (
"github.com/armadaproject/armada/internal/common"
log "github.com/armadaproject/armada/internal/common/logging"
- "github.com/armadaproject/armada/internal/lookoutingesterv2"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/benchmark"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/configuration"
+ "github.com/armadaproject/armada/internal/lookoutingester"
+ "github.com/armadaproject/armada/internal/lookoutingester/benchmark"
+ "github.com/armadaproject/armada/internal/lookoutingester/configuration"
)
const (
@@ -30,10 +30,10 @@ func main() {
log.MustConfigureApplicationLogging()
common.BindCommandlineArguments()
- var config configuration.LookoutIngesterV2Configuration
+ var config configuration.LookoutIngesterConfiguration
userSpecifiedConfigs := viper.GetStringSlice(CustomConfigLocation)
- common.LoadConfig(&config, "./config/lookoutingesterv2", userSpecifiedConfigs)
+ common.LoadConfig(&config, "./config/lookoutingester", userSpecifiedConfigs)
runBenchmarks := viper.GetBool(Benchmark)
if runBenchmarks {
@@ -42,5 +42,5 @@ func main() {
return
}
- lookoutingesterv2.Run(&config)
+ lookoutingester.Run(&config)
}
diff --git a/config/lookoutv2/config.yaml b/config/lookout/config.yaml
similarity index 100%
rename from config/lookoutv2/config.yaml
rename to config/lookout/config.yaml
diff --git a/config/lookoutingesterv2/config.yaml b/config/lookoutingester/config.yaml
similarity index 100%
rename from config/lookoutingesterv2/config.yaml
rename to config/lookoutingester/config.yaml
diff --git a/deployment/armada/README.md b/deployment/armada/README.md
index 30a74cc5d36..5f38112b9e9 100644
--- a/deployment/armada/README.md
+++ b/deployment/armada/README.md
@@ -43,6 +43,9 @@ helm uninstall armada-server
| additionalLabels | object | `{}` | Additional labels for all Armada Server K8s resources |
| additionalVolumeMounts | list | `[]` | Additional volume mounts for Armada Server Deployment resource |
| additionalVolumes | list | `[]` | Additional volumes for Armada Server Deployment resource |
+| applicationConfig.grpc.tls.certPath | string | `"/certs/tls.crt"` | |
+| applicationConfig.grpc.tls.enabled | bool | `false` | |
+| applicationConfig.grpc.tls.keyPath | string | `"/certs/tls.key"` | |
| applicationConfig.grpcPort | int | `50051` | Armada Server gRPC port |
| applicationConfig.httpPort | int | `8080` | Armada Server REST port |
| applicationConfig.pulsar.authenticationEnabled | bool | `false` | Toggle whether to mount Pulsar Token secret |
@@ -68,15 +71,19 @@ helm uninstall armada-server
| prometheus.enabled | bool | `false` | Toggle whether to install ServiceMonitor and PrometheusRule for Armada Server monitoring |
| prometheus.labels | object | `{}` | Additional labels for ServiceMonitor and PrometheusRule |
| prometheus.scrapeInterval | string | `"15s"` | Prometheus scrape interval |
+| prometheus.scrapeTimeout | string | `"10s"` | Prometheus scrape timeout |
| replicas | int | `1` | Armada Server replica count |
| resources.limits.cpu | string | `"300m"` | |
| resources.limits.memory | string | `"1Gi"` | |
| resources.requests.cpu | string | `"200m"` | |
| resources.requests.memory | string | `"512Mi"` | |
+| routableService.enabled | bool | `false` | |
| serviceAccount | object | `{}` | Additional ServiceAccount properties (e.g. automountServiceAccountToken, imagePullSecrets, etc.) |
+| serviceType | string | `"ClusterIP"` | |
| strategy.rollingUpdate.maxUnavailable | int | `1` | |
| strategy.type | string | `"RollingUpdate"` | |
| terminationGracePeriodSeconds | int | `30` | Number of seconds to wait for Armada Server to gracefully shutdown |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/binoculars/README.md b/deployment/binoculars/README.md
index 770d7a1748d..5cc2d12d921 100644
--- a/deployment/binoculars/README.md
+++ b/deployment/binoculars/README.md
@@ -8,7 +8,13 @@ A helm chart for Armada Binoculars component
| Key | Type | Default | Description |
|-----|------|---------|-------------|
+| additionalClusterRoleBindings | list | `[]` | |
| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
+| applicationConfig.grpc.tls.certPath | string | `"/certs/tls.crt"` | |
+| applicationConfig.grpc.tls.enabled | bool | `false` | |
+| applicationConfig.grpc.tls.keyPath | string | `"/certs/tls.key"` | |
| applicationConfig.grpcPort | int | `50051` | |
| applicationConfig.httpPort | int | `8080` | |
| applicationConfig.metricsPort | int | `9000` | |
@@ -20,6 +26,7 @@ A helm chart for Armada Binoculars component
| prometheus.enabled | bool | `false` | |
| prometheus.labels | object | `{}` | |
| prometheus.scrapeInterval | string | `"10s"` | |
+| prometheus.scrapeTimeout | string | `"10s"` | |
| replicas | int | `1` | |
| resources.limits.cpu | string | `"300m"` | |
| resources.limits.memory | string | `"1Gi"` | |
@@ -29,6 +36,7 @@ A helm chart for Armada Binoculars component
| strategy.rollingUpdate.maxUnavailable | int | `1` | |
| strategy.type | string | `"RollingUpdate"` | |
| terminationGracePeriodSeconds | int | `5` | |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/event-ingester/README.md b/deployment/event-ingester/README.md
index 3ca8ca5b5c5..1bb738555b8 100644
--- a/deployment/event-ingester/README.md
+++ b/deployment/event-ingester/README.md
@@ -9,12 +9,19 @@ A helm chart for Armada Event Ingester component
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
| applicationConfig.batchMessages | int | `10000` | |
| applicationConfig.batchSize | int | `1048576` | |
+| applicationConfig.metricsPort | int | `9000` | |
| applicationConfig.pulsar.authenticationEnabled | bool | `false` | |
| customServiceAccount | string | `nil` | |
| image.repository | string | `"gresearchdev/event-ingester-ingester"` | |
| image.tag | string | `"0.0.0-latest"` | |
+| prometheus.enabled | bool | `false` | |
+| prometheus.labels | object | `{}` | |
+| prometheus.scrapeInterval | string | `"15s"` | |
+| prometheus.scrapeTimeout | string | `"10s"` | |
| replicas | int | `1` | |
| resources.limits.cpu | string | `"300m"` | |
| resources.limits.memory | string | `"1Gi"` | |
@@ -24,6 +31,7 @@ A helm chart for Armada Event Ingester component
| strategy.rollingUpdate.maxUnavailable | int | `1` | |
| strategy.type | string | `"RollingUpdate"` | |
| terminationGracePeriodSeconds | int | `30` | |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/executor-cluster-monitoring/README.md b/deployment/executor-cluster-monitoring/README.md
index 29bdb0731db..2576e48563b 100644
--- a/deployment/executor-cluster-monitoring/README.md
+++ b/deployment/executor-cluster-monitoring/README.md
@@ -12,4 +12,4 @@ A helm chart for monitoring metrics of a cluster managed by a armada-executor co
| interval | string | `"10s"` | |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/executor/README.md b/deployment/executor/README.md
index c95142b2b24..b08d21c3701 100644
--- a/deployment/executor/README.md
+++ b/deployment/executor/README.md
@@ -8,22 +8,37 @@ A helm chart for armada-executor component
| Key | Type | Default | Description |
|-----|------|---------|-------------|
+| additionalClusterRoleBindings | list | `[]` | |
| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
| applicationConfig.apiConnection.armadaUrl | string | `""` | |
+| applicationConfig.httpPort | int | `8080` | |
| customServiceAccount | string | `nil` | |
+| healthcheck.enabled | bool | `false` | |
| image.repository | string | `"gresearchdev/armada-executor"` | |
| image.tag | string | `"0.0.0-latest"` | |
| nodeSelector | object | `{}` | |
+| priorityClassName | string | `""` | |
+| priorityClasses[0].description | string | `"Default priority class for pods created by Armada."` | |
+| priorityClasses[0].globalDefault | bool | `false` | |
+| priorityClasses[0].name | string | `"armada-default"` | |
+| priorityClasses[0].value | int | `1000` | |
+| priorityClasses[1].description | string | `"Priority class to be used for preemptible jobs."` | |
+| priorityClasses[1].globalDefault | bool | `false` | |
+| priorityClasses[1].name | string | `"armada-preemptible"` | |
+| priorityClasses[1].value | int | `900` | |
| prometheus.enabled | bool | `false` | |
| prometheus.labels | object | `{}` | |
| prometheus.scrapeInterval | string | `"10s"` | |
+| prometheus.scrapeTimeout | string | `"10s"` | |
| resources.limits.cpu | string | `"300m"` | |
| resources.limits.memory | string | `"1Gi"` | |
| resources.requests.cpu | string | `"200m"` | |
| resources.requests.memory | string | `"512Mi"` | |
| serviceAccount | string | `nil` | |
| terminationGracePeriodSeconds | int | `5` | |
-| tolerations | list | `[]` | |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/lookout-ingester-v2/README.md b/deployment/lookout-ingester-v2/README.md
index d56dda263a9..f3e31bac915 100644
--- a/deployment/lookout-ingester-v2/README.md
+++ b/deployment/lookout-ingester-v2/README.md
@@ -9,10 +9,17 @@ A helm chart for Armada Lookout Ingester v2 component
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
+| applicationConfig.metricsPort | int | `9000` | |
| applicationConfig.pulsar.authenticationEnabled | bool | `false` | |
| customServiceAccount | string | `nil` | |
-| image.repository | string | `"gresearchdev/armada-lookout-ingester"` | |
+| image.repository | string | `"gresearchdev/armada-lookout-ingester-v2"` | |
| image.tag | string | `"0.0.0-latest"` | |
+| prometheus.enabled | bool | `false` | |
+| prometheus.labels | object | `{}` | |
+| prometheus.scrapeInterval | string | `"15s"` | |
+| prometheus.scrapeTimeout | string | `"10s"` | |
| replicas | int | `1` | |
| resources.limits.cpu | string | `"300m"` | |
| resources.limits.memory | string | `"1Gi"` | |
@@ -22,6 +29,7 @@ A helm chart for Armada Lookout Ingester v2 component
| strategy.rollingUpdate.maxUnavailable | int | `1` | |
| strategy.type | string | `"RollingUpdate"` | |
| terminationGracePeriodSeconds | int | `30` | |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/lookout-ingester/Chart.yaml b/deployment/lookout-ingester/Chart.yaml
new file mode 100644
index 00000000000..55f5f8acffb
--- /dev/null
+++ b/deployment/lookout-ingester/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+description: A helm chart for Armada Lookout Ingester component
+name: armada-lookout-ingester
+version: 0.0.0-latest
+appVersion: 0.0.0-latest
diff --git a/deployment/lookout-ingester/README.md b/deployment/lookout-ingester/README.md
new file mode 100644
index 00000000000..94ae4108039
--- /dev/null
+++ b/deployment/lookout-ingester/README.md
@@ -0,0 +1,35 @@
+# armada-lookout-ingester
+
+ 
+
+A helm chart for Armada Lookout Ingester component
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
+| applicationConfig.metricsPort | int | `9000` | |
+| applicationConfig.pulsar.authenticationEnabled | bool | `false` | |
+| customServiceAccount | string | `nil` | |
+| image.repository | string | `"gresearchdev/armada-lookout-ingester"` | |
+| image.tag | string | `"0.0.0-latest"` | |
+| prometheus.enabled | bool | `false` | |
+| prometheus.labels | object | `{}` | |
+| prometheus.scrapeInterval | string | `"15s"` | |
+| prometheus.scrapeTimeout | string | `"10s"` | |
+| replicas | int | `1` | |
+| resources.limits.cpu | string | `"300m"` | |
+| resources.limits.memory | string | `"1Gi"` | |
+| resources.requests.cpu | string | `"200m"` | |
+| resources.requests.memory | string | `"512Mi"` | |
+| serviceAccount | string | `nil` | |
+| strategy.rollingUpdate.maxUnavailable | int | `1` | |
+| strategy.type | string | `"RollingUpdate"` | |
+| terminationGracePeriodSeconds | int | `30` | |
+| tolerations | list | `[]` | Tolerations |
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/lookout-ingester/templates/_helpers.tpl b/deployment/lookout-ingester/templates/_helpers.tpl
new file mode 100644
index 00000000000..d6cf846c237
--- /dev/null
+++ b/deployment/lookout-ingester/templates/_helpers.tpl
@@ -0,0 +1,43 @@
+
+{{- define "lookout_ingester.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "lookout_ingester.config.name" -}}
+{{- printf "%s-%s" ( include "lookout_ingester.name" .) "config" -}}
+{{- end }}
+
+{{- define "lookout_ingester.config.filename" -}}
+{{- printf "%s%s" ( include "lookout_ingester.config.name" .) ".yaml" -}}
+{{- end }}
+
+{{- define "lookout_ingester.users.name" -}}
+{{- printf "%s-%s" ( include "lookout_ingester.name" .) "users" -}}
+{{- end }}
+
+{{- define "lookout_ingester.users.filename" -}}
+{{- printf "%s%s" ( include "lookout_ingester.users.name" .) ".yaml" -}}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "lookout_ingester.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "lookout_ingester.labels.identity" -}}
+app: {{ include "lookout_ingester.name" . }}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "lookout_ingester.labels.all" -}}
+{{ include "lookout_ingester.labels.identity" . }}
+chart: {{ include "lookout_ingester.chart" . }}
+release: {{ .Release.Name }}
+{{- if .Values.additionalLabels }}
+{{ toYaml .Values.additionalLabels }}
+{{- end }}
+{{- end -}}
diff --git a/deployment/lookout-ingester/templates/configmap.yaml b/deployment/lookout-ingester/templates/configmap.yaml
new file mode 100644
index 00000000000..93d1e33f693
--- /dev/null
+++ b/deployment/lookout-ingester/templates/configmap.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "lookout_ingester.config.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 4 }}
+data:
+ {{ include "lookout_ingester.config.filename" . }}: |
+{{- if .Values.applicationConfig }}
+{{ toYaml .Values.applicationConfig | indent 4 }}
+{{- end }}
diff --git a/deployment/lookout-ingester/templates/deployment.yaml b/deployment/lookout-ingester/templates/deployment.yaml
new file mode 100644
index 00000000000..79d41628884
--- /dev/null
+++ b/deployment/lookout-ingester/templates/deployment.yaml
@@ -0,0 +1,110 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "lookout_ingester.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicas }}
+ selector:
+ matchLabels:
+ {{- include "lookout_ingester.labels.identity" . | nindent 6 }}
+ {{- if .Values.strategy }}
+ strategy:
+ {{- toYaml .Values.strategy | nindent 4 }}
+ {{- end }}
+ template:
+ metadata:
+ name: {{ include "lookout_ingester.name" . }}
+ annotations:
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 8 }}
+ spec:
+ terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
+ serviceAccountName: {{ .Values.customServiceAccount | default (include "lookout_ingester.name" .) }}
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 2000
+ {{- if .Values.tolerations }}
+ tolerations:
+ {{- toYaml .Values.tolerations | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: lookout-ingester
+ imagePullPolicy: IfNotPresent
+ image: {{ .Values.image.repository }}:{{ required "A value is required for .Values.image.tag" .Values.image.tag }}
+ args:
+ - --config
+ - /config/application_config.yaml
+ {{- if .Values.env }}
+ env:
+ {{- toYaml .Values.env | nindent 12 -}}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ ports:
+ {{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
+ - containerPort: {{ .Values.applicationConfig.profiling.port }}
+ protocol: TCP
+ name: profiling
+ {{- end }}
+ - containerPort: {{ .Values.applicationConfig.metricsPort }}
+ protocol: TCP
+ name: metrics
+ volumeMounts:
+ - name: user-config
+ mountPath: /config/application_config.yaml
+ subPath: {{ include "lookout_ingester.config.filename" . }}
+ readOnly: true
+ {{- if .Values.applicationConfig.pulsar.authenticationEnabled }}
+ - name: pulsar-token
+ mountPath: "/pulsar/tokens"
+ readOnly: true
+ {{- end }}
+ {{- if .Values.applicationConfig.pulsar.tlsEnabled }}
+ - name: pulsar-ca
+ mountPath: "/pulsar/ca"
+ readOnly: true
+ {{- end }}
+ {{- if .Values.additionalVolumeMounts }}
+ {{- toYaml .Values.additionalVolumeMounts | nindent 12 -}}
+ {{- end }}
+ securityContext:
+ allowPrivilegeEscalation: false
+ affinity:
+ podAntiAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchExpressions:
+ - key: app
+ operator: In
+ values:
+ - {{ include "lookout_ingester.name" . }}
+ topologyKey: kubernetes.io/hostname
+ volumes:
+ - name: user-config
+ configMap:
+ name: {{ include "lookout_ingester.config.name" . }}
+ {{- if .Values.applicationConfig.pulsar.authenticationEnabled }}
+ - name: pulsar-token
+ secret:
+ secretName: {{ .Values.applicationConfig.pulsar.authenticationSecret | default "armada-pulsar-token-armada-admin" | quote }}
+ items:
+ - key: TOKEN
+ path: pulsar-token
+ {{- end }}
+ {{- if .Values.applicationConfig.pulsar.tlsEnabled }}
+ - name: pulsar-ca
+ secret:
+ secretName: {{ .Values.applicationConfig.pulsar.cacert | default "armada-pulsar-ca-tls" | quote }}
+ items:
+ - key: ca.crt
+ path: ca.crt
+ {{- end }}
+ {{- if .Values.additionalVolumes }}
+ {{- toYaml .Values.additionalVolumes | nindent 8 }}
+ {{- end }}
diff --git a/deployment/lookout-ingester/templates/profiling-ingress.yaml b/deployment/lookout-ingester/templates/profiling-ingress.yaml
new file mode 100644
index 00000000000..af11159d2a8
--- /dev/null
+++ b/deployment/lookout-ingester/templates/profiling-ingress.yaml
@@ -0,0 +1,35 @@
+{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.hostnames }}
+{{- $root := . -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ include "lookout_ingester.name" . }}-profiling
+ namespace: {{ .Release.Namespace }}
+ annotations:
+ certmanager.k8s.io/cluster-issuer: {{ required "A value is required for .Values.applicationConfig.profiling.clusterIssuer" .Values.applicationConfig.profiling.clusterIssuer }}
+ cert-manager.io/cluster-issuer: {{ required "A value is required for .Values.applicationConfig.profiling.clusterIssuer" .Values.applicationConfig.profiling.clusterIssuer }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 4 }}
+spec:
+ rules:
+ {{- range required "A value is required for .Values.applicationConfig.profiling.hostnames" .Values.applicationConfig.profiling.hostnames }}
+ - host: {{ . }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ include "lookout_ingester.name" $root }}-profiling
+ port:
+ number: {{ $root.Values.applicationConfig.profiling.port }}
+ {{ end -}}
+ tls:
+ - hosts:
+ {{- range required "A value is required for .Values.applicationConfig.profiling.hostnames" .Values.applicationConfig.profiling.hostnames }}
+ - {{ . -}}
+ {{ end }}
+ secretName: {{ include "lookout_ingester.name" $root }}-profiling-service-tls
+---
+{{- end }}
+
diff --git a/deployment/lookout-ingester/templates/profiling-service.yaml b/deployment/lookout-ingester/templates/profiling-service.yaml
new file mode 100644
index 00000000000..c5a75b27d3e
--- /dev/null
+++ b/deployment/lookout-ingester/templates/profiling-service.yaml
@@ -0,0 +1,19 @@
+{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "lookout_ingester.name" . }}-profiling
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 4 }}
+ name: {{ include "lookout_ingester.name" . }}-profiling
+spec:
+ selector:
+ app: {{ include "lookout_ingester.name" . }}
+ ports:
+ - name: profiling
+ protocol: TCP
+ port: {{ .Values.applicationConfig.profiling.port }}
+---
+{{- end }}
+
diff --git a/deployment/lookout-ingester/templates/service.yaml b/deployment/lookout-ingester/templates/service.yaml
new file mode 100644
index 00000000000..6470311a24f
--- /dev/null
+++ b/deployment/lookout-ingester/templates/service.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "lookout_ingester.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 4 }}
+spec:
+ selector:
+ {{- include "lookout_ingester.labels.identity" . | nindent 4 }}
+ ports:
+ - name: metrics
+ protocol: TCP
+ port: {{ .Values.applicationConfig.metricsPort }}
diff --git a/deployment/lookout-ingester/templates/serviceaccount.yaml b/deployment/lookout-ingester/templates/serviceaccount.yaml
new file mode 100644
index 00000000000..77769f99589
--- /dev/null
+++ b/deployment/lookout-ingester/templates/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{ if not .Values.customServiceAccount }}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "lookout_ingester.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 4 }}
+ {{ if .Values.serviceAccount }}
+ {{ toYaml .Values.serviceAccount }}
+ {{ end }}
+ {{ end }}
diff --git a/deployment/lookout-ingester/templates/servicemonitor.yaml b/deployment/lookout-ingester/templates/servicemonitor.yaml
new file mode 100644
index 00000000000..0669817bb82
--- /dev/null
+++ b/deployment/lookout-ingester/templates/servicemonitor.yaml
@@ -0,0 +1,20 @@
+{{- if .Values.prometheus.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ include "lookout_ingester.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout_ingester.labels.all" . | nindent 4 -}}
+ {{- if .Values.prometheus.labels }}
+ {{- toYaml .Values.prometheus.labels | nindent 4 -}}
+ {{- end }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "lookout_ingester.labels.identity" . | nindent 6 }}
+ endpoints:
+ - port: metrics
+ interval: {{ .Values.prometheus.scrapeInterval }}
+ scrapeTimeout: {{ .Values.prometheus.scrapeTimeout }}
+{{- end }}
diff --git a/deployment/lookout-ingester/values.yaml b/deployment/lookout-ingester/values.yaml
new file mode 100644
index 00000000000..06fd724a9b4
--- /dev/null
+++ b/deployment/lookout-ingester/values.yaml
@@ -0,0 +1,34 @@
+image:
+ repository: gresearchdev/armada-lookout-ingester
+ tag: 0.0.0-latest
+resources:
+ limits:
+ memory: 1Gi
+ cpu: 300m
+ requests:
+ memory: 512Mi
+ cpu: 200m
+# -- Tolerations
+tolerations: []
+additionalLabels: {}
+additionalVolumeMounts: []
+additionalVolumes: []
+terminationGracePeriodSeconds: 30
+replicas: 1
+strategy:
+ rollingUpdate:
+ maxUnavailable: 1
+ type: RollingUpdate
+customServiceAccount: null
+serviceAccount: null
+
+applicationConfig:
+ metricsPort: 9000
+ pulsar:
+ authenticationEnabled: false
+
+prometheus:
+ enabled: false
+ labels: {}
+ scrapeInterval: 15s
+ scrapeTimeout: 10s
diff --git a/deployment/lookout-migration-v2/README.md b/deployment/lookout-migration-v2/README.md
index 87e0af258d1..f4070f79bea 100644
--- a/deployment/lookout-migration-v2/README.md
+++ b/deployment/lookout-migration-v2/README.md
@@ -2,22 +2,25 @@
 
-A Helm chart for the Armada Lookout database migration
+A Helm chart for the Armada Lookout v2 database migration
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
| applicationConfig | object | `{}` | |
| customServiceAccount | string | `nil` | |
-| image.repository | string | `"gresearchdev/armada-lookout"` | |
+| image.repository | string | `"gresearchdev/armada-lookout-v2"` | |
| image.tag | string | `"0.0.0-latest"` | |
| resources.limits.cpu | string | `"200m"` | |
| resources.limits.memory | string | `"256Mi"` | |
| resources.requests.cpu | string | `"100m"` | |
| resources.requests.memory | string | `"128Mi"` | |
| serviceAccount | string | `nil` | |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/lookout-migration/Chart.yaml b/deployment/lookout-migration/Chart.yaml
new file mode 100644
index 00000000000..8467822258b
--- /dev/null
+++ b/deployment/lookout-migration/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+description: A Helm chart for the Armada Lookout database migration
+name: armada-lookout-migration
+version: 0.0.0-latest
+appVersion: 0.0.0-latest
diff --git a/deployment/lookout-migration/README.md b/deployment/lookout-migration/README.md
new file mode 100644
index 00000000000..dc63a62df0a
--- /dev/null
+++ b/deployment/lookout-migration/README.md
@@ -0,0 +1,26 @@
+# armada-lookout-migration
+
+ 
+
+A Helm chart for the Armada Lookout database migration
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
+| applicationConfig | object | `{}` | |
+| customServiceAccount | string | `nil` | |
+| image.repository | string | `"gresearchdev/armada-lookout"` | |
+| image.tag | string | `"0.0.0-latest"` | |
+| resources.limits.cpu | string | `"200m"` | |
+| resources.limits.memory | string | `"256Mi"` | |
+| resources.requests.cpu | string | `"100m"` | |
+| resources.requests.memory | string | `"128Mi"` | |
+| serviceAccount | string | `nil` | |
+| tolerations | list | `[]` | Tolerations |
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/lookout-migration/templates/_helpers.tpl b/deployment/lookout-migration/templates/_helpers.tpl
new file mode 100644
index 00000000000..5ef94d64b52
--- /dev/null
+++ b/deployment/lookout-migration/templates/_helpers.tpl
@@ -0,0 +1,43 @@
+
+{{- define "lookout.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "lookout.config.name" -}}
+{{- printf "%s-%s" ( include "lookout.name" .) "config" -}}
+{{- end }}
+
+{{- define "lookout.config.filename" -}}
+{{- printf "%s%s" ( include "lookout.config.name" .) ".yaml" -}}
+{{- end }}
+
+{{- define "lookout.users.name" -}}
+{{- printf "%s-%s" ( include "lookout.name" .) "users" -}}
+{{- end }}
+
+{{- define "lookout.users.filename" -}}
+{{- printf "%s%s" ( include "lookout.users.name" .) ".yaml" -}}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "lookout.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "lookout.labels.identity" -}}
+app: {{ include "lookout.name" . }}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "lookout.labels.all" -}}
+{{ include "lookout.labels.identity" . }}
+chart: {{ include "lookout.chart" . }}
+release: {{ .Release.Name }}
+{{- if .Values.additionalLabels }}
+{{ toYaml .Values.additionalLabels }}
+{{- end }}
+{{- end -}}
diff --git a/deployment/lookout-migration/templates/configmap.yaml b/deployment/lookout-migration/templates/configmap.yaml
new file mode 100644
index 00000000000..be06092eae9
--- /dev/null
+++ b/deployment/lookout-migration/templates/configmap.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "lookout.config.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+data:
+ {{ include "lookout.config.filename" . }}: |
+{{- if .Values.applicationConfig }}
+{{ toYaml .Values.applicationConfig | indent 4 }}
+{{- end }}
diff --git a/deployment/lookout-migration/templates/job.yaml b/deployment/lookout-migration/templates/job.yaml
new file mode 100644
index 00000000000..ee7ed30399c
--- /dev/null
+++ b/deployment/lookout-migration/templates/job.yaml
@@ -0,0 +1,56 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ include "lookout.name" . }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+spec:
+ backoffLimit: 0
+ completions: 1
+ parallelism: 1
+ template:
+ metadata:
+ name: {{ include "lookout.name" . }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 8 }}
+ spec:
+ restartPolicy: Never
+ serviceAccountName: {{ .Values.customServiceAccount | default (include "lookout.name" .) }}
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 2000
+ {{- if .Values.tolerations }}
+ tolerations:
+ {{- toYaml .Values.tolerations | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: lookout
+ imagePullPolicy: IfNotPresent
+ image: {{ .Values.image.repository }}:{{ required "A value is required for .Values.image.tag" .Values.image.tag }}
+ args:
+ - --migrateDatabase
+ - --config
+ - /config/application_config.yaml
+ {{- if .Values.env }}
+ env:
+ {{- toYaml .Values.env | nindent 12 -}}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ volumeMounts:
+ - name: user-config
+ mountPath: /config/application_config.yaml
+ subPath: {{ include "lookout.config.filename" . }}
+ readOnly: true
+ {{- if .Values.additionalVolumeMounts }}
+ {{- toYaml .Values.additionalVolumeMounts | nindent 12 -}}
+ {{- end }}
+ securityContext:
+ allowPrivilegeEscalation: false
+ volumes:
+ - name: user-config
+ configMap:
+ name: {{ include "lookout.config.name" . }}
+ {{- if .Values.additionalVolumes }}
+ {{- toYaml .Values.additionalVolumes | nindent 8 }}
+ {{- end }}
diff --git a/deployment/lookout-migration/templates/serviceaccount.yaml b/deployment/lookout-migration/templates/serviceaccount.yaml
new file mode 100644
index 00000000000..d79b4cfeb07
--- /dev/null
+++ b/deployment/lookout-migration/templates/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{ if not .Values.customServiceAccount }}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "lookout.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+{{ if .Values.serviceAccount }}
+{{ toYaml .Values.serviceAccount }}
+{{ end }}
+{{ end }}
diff --git a/deployment/lookout-migration/values.yaml b/deployment/lookout-migration/values.yaml
new file mode 100644
index 00000000000..edbd8396c74
--- /dev/null
+++ b/deployment/lookout-migration/values.yaml
@@ -0,0 +1,19 @@
+image:
+ repository: gresearchdev/armada-lookout
+ tag: 0.0.0-latest
+resources:
+ limits:
+ memory: 256Mi
+ cpu: 200m
+ requests:
+ memory: 128Mi
+ cpu: 100m
+# -- Tolerations
+tolerations: []
+additionalLabels: {}
+additionalVolumeMounts: []
+additionalVolumes: []
+customServiceAccount: null
+serviceAccount: null
+
+applicationConfig: {}
diff --git a/deployment/lookout-v2/README.md b/deployment/lookout-v2/README.md
index 554855dd8d4..a943d5b0820 100644
--- a/deployment/lookout-v2/README.md
+++ b/deployment/lookout-v2/README.md
@@ -2,18 +2,21 @@
 
-A helm chart for Armada Lookout component
+A helm chart for Armada Lookout v2 component
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| additionalLabels | object | `{}` | |
-| applicationConfig.grpcPort | int | `50051` | |
-| applicationConfig.httpPort | int | `8080` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
+| applicationConfig.apiPort | int | `10000` | |
| applicationConfig.metricsPort | int | `9000` | |
+| applicationConfig.tls.enabled | bool | `false` | |
| customServiceAccount | string | `nil` | |
-| image.repository | string | `"gresearchdev/armada-lookout"` | |
+| dbPruningEnabled | bool | `true` | |
+| image.repository | string | `"gresearchdev/armada-lookout-v2-dev"` | |
| image.tag | string | `"0.0.0-latest"` | |
| ingress.annotations | object | `{}` | |
| ingress.labels | object | `{}` | |
@@ -25,10 +28,12 @@ A helm chart for Armada Lookout component
| resources.limits.memory | string | `"1Gi"` | |
| resources.requests.cpu | string | `"200m"` | |
| resources.requests.memory | string | `"512Mi"` | |
+| routableService.enabled | bool | `false` | |
| serviceAccount | string | `nil` | |
| strategy.rollingUpdate.maxUnavailable | int | `1` | |
| strategy.type | string | `"RollingUpdate"` | |
| terminationGracePeriodSeconds | int | `5` | |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/lookout/Chart.yaml b/deployment/lookout/Chart.yaml
new file mode 100644
index 00000000000..5757983b788
--- /dev/null
+++ b/deployment/lookout/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+description: A helm chart for Armada Lookout component
+name: armada-lookout
+version: 0.0.0-latest
+appVersion: 0.0.0-latest
diff --git a/deployment/lookout/README.md b/deployment/lookout/README.md
new file mode 100644
index 00000000000..2c87c88bd6c
--- /dev/null
+++ b/deployment/lookout/README.md
@@ -0,0 +1,39 @@
+# armada-lookout
+
+ 
+
+A helm chart for Armada Lookout component
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| additionalLabels | object | `{}` | |
+| additionalVolumeMounts | list | `[]` | |
+| additionalVolumes | list | `[]` | |
+| applicationConfig.apiPort | int | `10000` | |
+| applicationConfig.metricsPort | int | `9000` | |
+| applicationConfig.tls.enabled | bool | `false` | |
+| customServiceAccount | string | `nil` | |
+| dbPruningEnabled | bool | `true` | |
+| image.repository | string | `"gresearchdev/armada-lookout-dev"` | |
+| image.tag | string | `"0.0.0-latest"` | |
+| ingress.annotations | object | `{}` | |
+| ingress.labels | object | `{}` | |
+| prometheus.enabled | bool | `false` | |
+| prometheus.labels | object | `{}` | |
+| prometheus.scrapeInterval | string | `"10s"` | |
+| replicas | int | `1` | |
+| resources.limits.cpu | string | `"300m"` | |
+| resources.limits.memory | string | `"1Gi"` | |
+| resources.requests.cpu | string | `"200m"` | |
+| resources.requests.memory | string | `"512Mi"` | |
+| routableService.enabled | bool | `false` | |
+| serviceAccount | string | `nil` | |
+| strategy.rollingUpdate.maxUnavailable | int | `1` | |
+| strategy.type | string | `"RollingUpdate"` | |
+| terminationGracePeriodSeconds | int | `5` | |
+| tolerations | list | `[]` | Tolerations |
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/lookout/templates/_helpers.tpl b/deployment/lookout/templates/_helpers.tpl
new file mode 100644
index 00000000000..5ef94d64b52
--- /dev/null
+++ b/deployment/lookout/templates/_helpers.tpl
@@ -0,0 +1,43 @@
+
+{{- define "lookout.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "lookout.config.name" -}}
+{{- printf "%s-%s" ( include "lookout.name" .) "config" -}}
+{{- end }}
+
+{{- define "lookout.config.filename" -}}
+{{- printf "%s%s" ( include "lookout.config.name" .) ".yaml" -}}
+{{- end }}
+
+{{- define "lookout.users.name" -}}
+{{- printf "%s-%s" ( include "lookout.name" .) "users" -}}
+{{- end }}
+
+{{- define "lookout.users.filename" -}}
+{{- printf "%s%s" ( include "lookout.users.name" .) ".yaml" -}}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "lookout.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "lookout.labels.identity" -}}
+app: {{ include "lookout.name" . }}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "lookout.labels.all" -}}
+{{ include "lookout.labels.identity" . }}
+chart: {{ include "lookout.chart" . }}
+release: {{ .Release.Name }}
+{{- if .Values.additionalLabels }}
+{{ toYaml .Values.additionalLabels }}
+{{- end }}
+{{- end -}}
diff --git a/deployment/lookout/templates/configmap.yaml b/deployment/lookout/templates/configmap.yaml
new file mode 100644
index 00000000000..be06092eae9
--- /dev/null
+++ b/deployment/lookout/templates/configmap.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "lookout.config.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+data:
+ {{ include "lookout.config.filename" . }}: |
+{{- if .Values.applicationConfig }}
+{{ toYaml .Values.applicationConfig | indent 4 }}
+{{- end }}
diff --git a/deployment/lookout/templates/cronjob.yaml b/deployment/lookout/templates/cronjob.yaml
new file mode 100644
index 00000000000..5d0415fec89
--- /dev/null
+++ b/deployment/lookout/templates/cronjob.yaml
@@ -0,0 +1,60 @@
+{{ if .Values.dbPruningEnabled}}
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+ name: {{ include "lookout.name" . }}-db-pruner
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+spec:
+ schedule: {{ .Values.dbPruneSchedule | default "@hourly" | quote }}
+ concurrencyPolicy: Forbid
+ jobTemplate:
+ metadata:
+ name: {{ include "lookout.name" . }}-db-pruner
+ labels:
+ {{- include "lookout.labels.all" . | nindent 8 }}
+ spec:
+ backoffLimit: 6
+ template:
+ metadata:
+ name: {{ include "lookout.name" . }}-db-pruner
+ labels:
+ {{- include "lookout.labels.all" . | nindent 12 }}
+ spec:
+ restartPolicy: Never
+ serviceAccountName: {{ .Values.customServiceAccount | default (include "lookout.name" .) }}
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 2000
+ containers:
+ - name: lookout-db-pruner
+ imagePullPolicy: IfNotPresent
+ image: {{ .Values.image.repository }}:{{ required "A value is required for .Values.image.tag" .Values.image.tag }}
+ args:
+ - --pruneDatabase
+ - --config
+ - /config/application_config.yaml
+ {{- if .Values.env }}
+ env:
+ {{- toYaml .Values.env | nindent 16 -}}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.resources | nindent 16 }}
+ volumeMounts:
+ - name: user-config
+ mountPath: /config/application_config.yaml
+ subPath: {{ include "lookout.config.filename" . }}
+ readOnly: true
+ {{- if .Values.additionalVolumeMounts }}
+ {{- toYaml .Values.additionalVolumeMounts | nindent 16 -}}
+ {{- end }}
+ securityContext:
+ allowPrivilegeEscalation: false
+ volumes:
+ - name: user-config
+ configMap:
+ name: {{ include "lookout.config.name" . }}
+ {{- if .Values.additionalVolumes }}
+ {{- toYaml .Values.additionalVolumes | nindent 12 }}
+ {{- end }}
+{{- end }}
diff --git a/deployment/lookout/templates/deployment.yaml b/deployment/lookout/templates/deployment.yaml
new file mode 100644
index 00000000000..7307337b694
--- /dev/null
+++ b/deployment/lookout/templates/deployment.yaml
@@ -0,0 +1,113 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "lookout.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicas }}
+ selector:
+ matchLabels:
+ {{- include "lookout.labels.identity" . | nindent 6 }}
+ {{- if .Values.strategy }}
+ strategy:
+ {{- toYaml .Values.strategy | nindent 4 }}
+ {{- end }}
+ template:
+ metadata:
+ name: {{ include "lookout.name" . }}
+ annotations:
+ checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 8 }}
+ spec:
+ terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
+ serviceAccountName: {{ .Values.customServiceAccount | default (include "lookout.name" .) }}
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 2000
+ {{- if .Values.tolerations }}
+ tolerations:
+ {{- toYaml .Values.tolerations | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: lookout
+ imagePullPolicy: IfNotPresent
+ image: {{ .Values.image.repository }}:{{ required "A value is required for .Values.image.tag" .Values.image.tag }}
+ args:
+ - --config
+ - /config/application_config.yaml
+ {{- if .Values.env }}
+ env:
+ {{- toYaml .Values.env | nindent 12 -}}
+ {{- end }}
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ ports:
+ - containerPort: {{ .Values.applicationConfig.apiPort }}
+ protocol: TCP
+ name: web
+ {{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
+ - containerPort: {{ .Values.applicationConfig.profiling.port }}
+ protocol: TCP
+ name: profiling
+ {{- end }}
+ - containerPort: {{ .Values.applicationConfig.metricsPort }}
+ protocol: TCP
+ name: metrics
+ volumeMounts:
+ - name: user-config
+ mountPath: /config/application_config.yaml
+ subPath: {{ include "lookout.config.filename" . }}
+ readOnly: true
+ {{- if .Values.applicationConfig.tls.enabled }}
+ - name: tls-certs
+ mountPath: /certs
+ readOnly: true
+ {{- end }}
+ {{- if .Values.additionalVolumeMounts }}
+ {{- toYaml .Values.additionalVolumeMounts | nindent 12 -}}
+ {{- end }}
+ securityContext:
+ allowPrivilegeEscalation: false
+ readinessProbe:
+ httpGet:
+ path: /health
+ port: web
+ scheme: {{ if .Values.applicationConfig.tls.enabled }}HTTPS{{ else }}HTTP{{ end }}
+ initialDelaySeconds: 5
+ timeoutSeconds: 5
+ failureThreshold: 2
+ livenessProbe:
+ httpGet:
+ path: /health
+ port: web
+ scheme: {{ if .Values.applicationConfig.tls.enabled }}HTTPS{{ else }}HTTP{{ end }}
+ initialDelaySeconds: 10
+ timeoutSeconds: 10
+ failureThreshold: 3
+ affinity:
+ podAntiAffinity:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ - weight: 100
+ podAffinityTerm:
+ labelSelector:
+ matchExpressions:
+ - key: app
+ operator: In
+ values:
+ - {{ include "lookout.name" . }}
+ topologyKey: kubernetes.io/hostname
+ volumes:
+ - name: user-config
+ configMap:
+ name: {{ include "lookout.config.name" . }}
+ {{- if .Values.applicationConfig.tls.enabled }}
+ - name: tls-certs
+ secret:
+ secretName: {{ include "lookout.name" . }}-service-tls
+ {{- end }}
+ {{- if .Values.additionalVolumes }}
+ {{- toYaml .Values.additionalVolumes | nindent 8 }}
+ {{- end }}
diff --git a/deployment/lookout/templates/ingressweb.yaml b/deployment/lookout/templates/ingressweb.yaml
new file mode 100644
index 00000000000..5bc4f9ca165
--- /dev/null
+++ b/deployment/lookout/templates/ingressweb.yaml
@@ -0,0 +1,37 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ include "lookout.name" . }}-web
+ namespace: {{ .Release.Namespace }}
+ annotations:
+ kubernetes.io/ingress.class: {{ required "A value is required for .Values.ingressClass" .Values.ingressClass }}
+ nginx.ingress.kubernetes.io/ssl-redirect: "true"
+ certmanager.k8s.io/cluster-issuer: {{ required "A value is required for .Values.clusterIssuer" .Values.clusterIssuer }}
+ cert-manager.io/cluster-issuer: {{ required "A value is required for .Values.clusterIssuer" .Values.clusterIssuer }}
+ {{- if .Values.ingress.annotations }}
+ {{- toYaml .Values.ingress.annotations | nindent 4 -}}
+ {{- end }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+ {{- if .Values.ingress.labels }}
+ {{- toYaml .Values.ingress.labels | nindent 4 -}}
+ {{- end }}
+spec:
+ rules:
+ {{- $root := . -}}
+ {{ range required "A value is required for .Values.hostnames" .Values.hostnames }}
+ - host: {{ . }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ include "lookout.name" $root }}
+ port:
+ number: {{ $root.Values.applicationConfig.apiPort }}
+ {{ end }}
+ tls:
+ - hosts:
+ {{- toYaml .Values.hostnames | nindent 8 }}
+ secretName: {{ include "lookout.name" . }}-service-tls
diff --git a/deployment/lookout/templates/profiling-ingress.yaml b/deployment/lookout/templates/profiling-ingress.yaml
new file mode 100644
index 00000000000..9b78c936d99
--- /dev/null
+++ b/deployment/lookout/templates/profiling-ingress.yaml
@@ -0,0 +1,35 @@
+{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.hostnames }}
+{{- $root := . -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ include "lookout.name" . }}-profiling
+ namespace: {{ .Release.Namespace }}
+ annotations:
+ certmanager.k8s.io/cluster-issuer: {{ required "A value is required for .Values.applicationConfig.profiling.clusterIssuer" .Values.applicationConfig.profiling.clusterIssuer }}
+ cert-manager.io/cluster-issuer: {{ required "A value is required for .Values.applicationConfig.profiling.clusterIssuer" .Values.applicationConfig.profiling.clusterIssuer }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+spec:
+ rules:
+ {{- range required "A value is required for .Values.applicationConfig.profiling.hostnames" .Values.applicationConfig.profiling.hostnames }}
+ - host: {{ . }}
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: {{ include "lookout.name" $root }}-profiling
+ port:
+ number: {{ $root.Values.applicationConfig.profiling.port }}
+ {{ end -}}
+ tls:
+ - hosts:
+ {{- range required "A value is required for .Values.applicationConfig.profiling.hostnames" .Values.applicationConfig.profiling.hostnames }}
+ - {{ . -}}
+ {{ end }}
+ secretName: {{ include "lookout.name" $root }}-profiling-service-tls
+---
+{{- end }}
+
diff --git a/deployment/lookout/templates/profiling-service.yaml b/deployment/lookout/templates/profiling-service.yaml
new file mode 100644
index 00000000000..16b00bc651b
--- /dev/null
+++ b/deployment/lookout/templates/profiling-service.yaml
@@ -0,0 +1,19 @@
+{{- if and .Values.applicationConfig.profiling .Values.applicationConfig.profiling.port }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "lookout.name" . }}-profiling
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+ name: {{ include "lookout.name" . }}-profiling
+spec:
+ selector:
+ app: {{ include "lookout.name" . }}
+ ports:
+ - name: profiling
+ protocol: TCP
+ port: {{ .Values.applicationConfig.profiling.port }}
+---
+{{- end }}
+
diff --git a/deployment/lookout/templates/routableservice.yaml b/deployment/lookout/templates/routableservice.yaml
new file mode 100644
index 00000000000..12c95c9c36f
--- /dev/null
+++ b/deployment/lookout/templates/routableservice.yaml
@@ -0,0 +1,22 @@
+{{ if .Values.routableService.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "lookout.name" . }}-routable
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+spec:
+ type: LoadBalancer
+ allocateLoadBalancerNodePorts: false
+ {{ if .Values.routableService.loadBalancerIP }}
+ loadBalancerIP: {{.Values.routableService.loadBalancerIP}}
+ {{ end }}
+ selector:
+ {{- include "lookout.labels.identity" . | nindent 4 }}
+ ports:
+ - name: web
+ protocol: TCP
+ port: {{ if .Values.applicationConfig.tls.enabled }}443{{ else }}80{{ end }}
+ targetPort: {{ .Values.applicationConfig.apiPort }}
+{{ end }}
diff --git a/deployment/lookout/templates/service.yaml b/deployment/lookout/templates/service.yaml
new file mode 100644
index 00000000000..6c819a80fd2
--- /dev/null
+++ b/deployment/lookout/templates/service.yaml
@@ -0,0 +1,24 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "lookout.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+spec:
+ {{- if .Values.nodePort }}
+ type: NodePort
+ {{- end }}
+ selector:
+ {{- include "lookout.labels.identity" . | nindent 4 }}
+ ports:
+ - name: web
+ protocol: TCP
+ port: {{ .Values.applicationConfig.apiPort }}
+ {{- if .Values.httpNodePort }}
+ nodePort: {{ .Values.httpNodePort }}
+ {{- end }}
+ - name: metrics
+ protocol: TCP
+ port: {{ .Values.applicationConfig.metricsPort }}
+
diff --git a/deployment/lookout/templates/serviceaccount.yaml b/deployment/lookout/templates/serviceaccount.yaml
new file mode 100644
index 00000000000..d79b4cfeb07
--- /dev/null
+++ b/deployment/lookout/templates/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{ if not .Values.customServiceAccount }}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "lookout.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 }}
+{{ if .Values.serviceAccount }}
+{{ toYaml .Values.serviceAccount }}
+{{ end }}
+{{ end }}
diff --git a/deployment/lookout/templates/servicemonitor.yaml b/deployment/lookout/templates/servicemonitor.yaml
new file mode 100644
index 00000000000..6167b9c6e9f
--- /dev/null
+++ b/deployment/lookout/templates/servicemonitor.yaml
@@ -0,0 +1,20 @@
+{{- if .Values.prometheus.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ include "lookout.name" . }}
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "lookout.labels.all" . | nindent 4 -}}
+ {{- if .Values.prometheus.labels }}
+ {{- toYaml .Values.prometheus.labels | nindent 4 -}}
+ {{- end }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "lookout.labels.identity" . | nindent 6 }}
+ endpoints:
+ - port: metrics
+ interval: {{ .Values.prometheus.scrapeInterval }}
+ scrapeTimeout: {{ .Values.prometheus.scrapeTimeout }}
+{{- end }}
diff --git a/deployment/lookout/values.yaml b/deployment/lookout/values.yaml
new file mode 100644
index 00000000000..e333682f005
--- /dev/null
+++ b/deployment/lookout/values.yaml
@@ -0,0 +1,40 @@
+image:
+ repository: gresearchdev/armada-lookout-dev
+ tag: 0.0.0-latest
+resources:
+ limits:
+ memory: 1Gi
+ cpu: 300m
+ requests:
+ memory: 512Mi
+ cpu: 200m
+# -- Tolerations
+tolerations: []
+additionalLabels: {}
+additionalVolumeMounts: []
+additionalVolumes: []
+dbPruningEnabled: true
+terminationGracePeriodSeconds: 5
+replicas: 1
+strategy:
+ rollingUpdate:
+ maxUnavailable: 1
+ type: RollingUpdate
+ingress:
+ annotations: {}
+ labels: {}
+prometheus:
+ enabled: false
+ labels: {}
+ scrapeInterval: 10s
+customServiceAccount: null
+serviceAccount: null
+
+routableService:
+ enabled: false
+
+applicationConfig:
+ tls:
+ enabled: false
+ apiPort: 10000
+ metricsPort: 9000
diff --git a/deployment/scheduler-migration/README.md b/deployment/scheduler-migration/README.md
index 7d8676959c9..4e11964d206 100644
--- a/deployment/scheduler-migration/README.md
+++ b/deployment/scheduler-migration/README.md
@@ -23,5 +23,4 @@ A Helm chart for the Armada Scheduler database migration
| serviceAccount | string | `nil` | |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
-
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/deployment/scheduler/README.md b/deployment/scheduler/README.md
index 41134d76b0a..d1a3f142580 100644
--- a/deployment/scheduler/README.md
+++ b/deployment/scheduler/README.md
@@ -1,6 +1,6 @@
# armada-scheduler
- 
+ 
A helm chart for Armada Scheduler component
@@ -11,11 +11,15 @@ A helm chart for Armada Scheduler component
| additionalLabels | object | `{}` | |
| ingester.additionalVolumeMounts | list | `[]` | |
| ingester.additionalVolumes | list | `[]` | |
-| ingester.applicationConfig.metrics.port | int | `9003` | |
+| ingester.applicationConfig.metricsPort | int | `9003` | |
| ingester.applicationConfig.pulsar | object | `{}` | |
| ingester.customServiceAccount | string | `nil` | |
| ingester.image.repository | string | `"gresearchdev/armada-scheduler-ingester"` | |
| ingester.image.tag | string | `"0.0.0-latest"` | |
+| ingester.prometheus.enabled | bool | `false` | |
+| ingester.prometheus.labels | object | `{}` | |
+| ingester.prometheus.scrapeInterval | string | `"15s"` | |
+| ingester.prometheus.scrapeTimeout | string | `"10s"` | |
| ingester.replicas | int | `1` | |
| ingester.resources.limits.cpu | string | `"300m"` | |
| ingester.resources.limits.memory | string | `"1Gi"` | |
@@ -25,6 +29,7 @@ A helm chart for Armada Scheduler component
| ingester.strategy.rollingUpdate.maxUnavailable | int | `1` | |
| ingester.strategy.type | string | `"RollingUpdate"` | |
| ingester.terminationGracePeriodSeconds | int | `30` | |
+| pruner.applicationConfig | object | `{}` | |
| pruner.args.batchsize | int | `10000` | |
| pruner.args.expireAfter | string | `"2h"` | |
| pruner.args.timeout | string | `"5m"` | |
@@ -37,31 +42,32 @@ A helm chart for Armada Scheduler component
| scheduler.additionalVolumeMounts | list | `[]` | |
| scheduler.additionalVolumes | list | `[]` | |
| scheduler.applicationConfig.grpc.port | int | `50051` | |
+| scheduler.applicationConfig.grpc.tls.certPath | string | `"/certs/tls.crt"` | |
+| scheduler.applicationConfig.grpc.tls.enabled | bool | `false` | |
+| scheduler.applicationConfig.grpc.tls.keyPath | string | `"/certs/tls.key"` | |
+| scheduler.applicationConfig.http.port | int | `8080` | |
+| scheduler.applicationConfig.metrics.port | int | `9001` | |
| scheduler.applicationConfig.pulsar | object | `{}` | |
-| scheduler.clusterIssuer | string | `"thing"` | |
| scheduler.customServiceAccount | string | `nil` | |
-| scheduler.hostnames[0] | string | `"test"` | |
| scheduler.image.repository | string | `"gresearchdev/armada-scheduler"` | |
| scheduler.image.tag | string | `"0.0.0-latest"` | |
| scheduler.ingress.annotations | object | `{}` | |
| scheduler.ingress.labels | object | `{}` | |
| scheduler.ingress.nameOverride | string | `""` | |
-| scheduler.ingressClass | string | `"val"` | |
| scheduler.prometheus.enabled | bool | `false` | |
| scheduler.prometheus.labels | object | `{}` | |
| scheduler.prometheus.scrapeInterval | string | `"15s"` | |
-| scheduler.pruner.enabled | bool | `true` | |
-| scheduler.pruner.schedule | string | `"@hourly"` | |
+| scheduler.prometheus.scrapeTimeout | string | `"10s"` | |
| scheduler.replicas | int | `1` | |
| scheduler.resources.limits.cpu | string | `"300m"` | |
| scheduler.resources.limits.memory | string | `"1Gi"` | |
| scheduler.resources.requests.cpu | string | `"200m"` | |
| scheduler.resources.requests.memory | string | `"512Mi"` | |
| scheduler.serviceAccount | string | `nil` | |
-| scheduler.strategy.rollingUpdate.maxUnavailable | int | `1` | |
-| scheduler.strategy.type | string | `"RollingUpdate"` | |
| scheduler.terminationGracePeriodSeconds | int | `30` | |
+| scheduler.updateStrategy.rollingUpdate.maxUnavailable | int | `1` | |
+| scheduler.updateStrategy.type | string | `"RollingUpdate"` | |
+| tolerations | list | `[]` | Tolerations |
----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.11.0](/~https://github.com/norwoodj/helm-docs/releases/v1.11.0)
-
+Autogenerated from chart metadata using [helm-docs v1.14.2](/~https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/developer/env/docker/lookoutv2.env b/developer/env/docker/lookout.env
similarity index 100%
rename from developer/env/docker/lookoutv2.env
rename to developer/env/docker/lookout.env
diff --git a/developer/env/local/lookoutv2.env b/developer/env/local/lookout.env
similarity index 100%
rename from developer/env/local/lookoutv2.env
rename to developer/env/local/lookout.env
diff --git a/docker-compose.yaml b/docker-compose.yaml
index ee5dd65ddb7..47ded4afd76 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -59,9 +59,9 @@ services:
- "go-cache:/root/.cache/go-build:rw"
- "gomod-cache:/go/pkg/mod:rw"
depends_on:
- - lookoutv2-migration
+ - lookout-migration
- eventingester
- - lookoutingesterv2
+ - lookoutingester
working_dir: /app
env_file:
- developer/env/docker/server.env
@@ -168,8 +168,8 @@ services:
working_dir: /app
command: ./eventingester
- lookoutv2:
- container_name: lookoutv2
+ lookout:
+ container_name: lookout
image: ${ARMADA_IMAGE:-gresearch/armada-lookout-bundle}:${ARMADA_IMAGE_TAG:-latest}
networks:
- kind
@@ -177,18 +177,18 @@ services:
- "10000:10000"
- "4005:4000"
depends_on:
- - lookoutingesterv2
+ - lookoutingester
volumes:
- "./internal/lookoutui/build:/app/internal/lookoutui/build"
- "go-cache:/root/.cache/go-build:rw"
- "gomod-cache:/go/pkg/mod:rw"
env_file:
- - ./developer/env/docker/lookoutv2.env
+ - developer/env/docker/lookout.env
working_dir: "/app"
- entrypoint: ./lookoutv2
+ entrypoint: ./lookout
- lookoutv2-migration:
- container_name: lookoutv2-migration
+ lookout-migration:
+ container_name: lookout-migration
image: ${ARMADA_IMAGE:-gresearch/armada-lookout-bundle}:${ARMADA_IMAGE_TAG:-latest}
networks:
- kind
@@ -198,12 +198,12 @@ services:
- "go-cache:/root/.cache/go-build:rw"
- "gomod-cache:/go/pkg/mod:rw"
env_file:
- - ./developer/env/docker/lookoutv2.env
+ - developer/env/docker/lookout.env
working_dir: "/app"
- entrypoint: ./lookoutv2 --migrateDatabase
+ entrypoint: ./lookout --migrateDatabase
- lookoutingesterv2:
- container_name: lookoutingesterv2
+ lookoutingester:
+ container_name: lookoutingester
image: ${ARMADA_IMAGE:-gresearch/armada-lookout-bundle}:${ARMADA_IMAGE_TAG:-latest}
ports:
- 4007:4000
@@ -213,9 +213,9 @@ services:
networks:
- kind
env_file:
- - ./developer/env/docker/lookoutv2.env
+ - developer/env/docker/lookout.env
working_dir: /app
- command: ./lookoutingesterv2
+ command: ./lookoutingester
airflow:
container_name: airflow
diff --git a/docs/developer.md b/docs/developer.md
index 315f7e5bfa7..cb346b35bea 100644
--- a/docs/developer.md
+++ b/docs/developer.md
@@ -217,16 +217,15 @@ All outputs of delve can be found in the `./delve` directory.
External Debug Port Mappings:
-|Armada service |Debug host |
-|-------------------|--------------|
-|server |localhost:4000|
-|executor |localhost:4001|
-|binoculars |localhost:4002|
-|eventingester |localhost:4003|
-|lookout |localhost:4004|
-|lookoutv2 |localhost:4005|
-|lookoutingester |localhost:4006|
-|lookoutingesterv2 |localhost:4007|
+| Armada service | Debug host |
+|-----------------|----------------|
+| server | localhost:4000 |
+| executor | localhost:4001 |
+| binoculars | localhost:4002 |
+| eventingester | localhost:4003 |
+| lookoutui | localhost:4004 |
+| lookout | localhost:4005 |
+| lookoutingester | localhost:4007 |
## GoLand Run Configurations
@@ -240,10 +239,10 @@ The following high-level configurations are provided, each composed of sub-confi
- Runs Armada with the Legacy Scheduler
3. `Armada (Pulsar Scheduler)`
- Runs Armada with the Pulsar Scheduler (recommended)
-4. `LookoutV2 UI`
+4. `Lookout UI`
- Script which configures a local UI development setup
-A minimal local Armada setup using these configurations would be `Armada Infrastructure Services` and one of (`Armada (Legacy Scheduler)` or `Armada (Pulsar Scheduler)`). Running the `LookoutV2 UI` script on top of this configuration would allow you to develop the Lookout UI live from GoLand, and see the changes visible in your browser. **These configurations (executor specifically) require a kubernetes config in `$PROJECT_DIR$/.kube/internal/config`**
+A minimal local Armada setup using these configurations would be `Armada Infrastructure Services` and one of (`Armada (Legacy Scheduler)` or `Armada (Pulsar Scheduler)`). Running the `Lookout UI` script on top of this configuration would allow you to develop the Lookout UI live from GoLand, and see the changes visible in your browser. **These configurations (executor specifically) require a kubernetes config in `$PROJECT_DIR$/.kube/internal/config`**
GoLand does not allow us to specify an ordering for services within docker compose configurations. As a result, some database migration services may require rerunning.
diff --git a/internal/common/database/lookout/util.go b/internal/common/database/lookout/util.go
index a4c4690a598..7626f60b834 100644
--- a/internal/common/database/lookout/util.go
+++ b/internal/common/database/lookout/util.go
@@ -4,7 +4,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"github.com/armadaproject/armada/internal/common/database"
- "github.com/armadaproject/armada/internal/lookoutv2/schema"
+ "github.com/armadaproject/armada/internal/lookout/schema"
)
func WithLookoutDb(action func(db *pgxpool.Pool) error) error {
diff --git a/internal/common/ingest/metrics/metrics.go b/internal/common/ingest/metrics/metrics.go
index 9e92f828004..517d61d4ce6 100644
--- a/internal/common/ingest/metrics/metrics.go
+++ b/internal/common/ingest/metrics/metrics.go
@@ -20,8 +20,8 @@ const (
)
const (
- ArmadaLookoutIngesterV2MetricsPrefix = "armada_lookout_ingester_v2_"
- ArmadaEventIngesterMetricsPrefix = "armada_event_ingester_"
+ ArmadaLookoutIngesterMetricsPrefix = "armada_lookout_ingester_v2_"
+ ArmadaEventIngesterMetricsPrefix = "armada_event_ingester_"
)
const (
diff --git a/internal/common/ingest/testfixtures/event.go b/internal/common/ingest/testfixtures/event.go
index fcb3769b6bd..7d5e45eef82 100644
--- a/internal/common/ingest/testfixtures/event.go
+++ b/internal/common/ingest/testfixtures/event.go
@@ -26,6 +26,7 @@ const (
ExecutorId = "testCluster"
ExecutorId2 = "testCluster2"
ExecutorId3 = "testCluster3"
+ CancelUser = "canceluser"
NodeName = "testNode"
Pool = "Pool"
PodName = "test-pod"
@@ -261,7 +262,8 @@ var JobCancelled = &armadaevents.EventSequence_Event{
Created: testfixtures.BasetimeProto,
Event: &armadaevents.EventSequence_Event_CancelledJob{
CancelledJob: &armadaevents.CancelledJob{
- JobId: JobId,
+ JobId: JobId,
+ CancelUser: CancelUser,
},
},
}
diff --git a/internal/common/resource/resource.go b/internal/common/resource/resource.go
index 00265f544eb..32317648e95 100644
--- a/internal/common/resource/resource.go
+++ b/internal/common/resource/resource.go
@@ -204,6 +204,19 @@ func (a ComputeResources) Sub(b ComputeResources) {
}
}
+func (a ComputeResources) Div(b map[string]int64) {
+ for k, v := range b {
+ existing, ok := a[k]
+ if ok {
+ if existing.Format == resource.DecimalSI {
+ a[k] = resource.NewMilliQuantity(existing.MilliValue()/v, existing.Format).DeepCopy()
+ } else {
+ a[k] = resource.NewQuantity(existing.Value()/v, existing.Format).DeepCopy()
+ }
+ }
+ }
+}
+
func (a ComputeResources) DeepCopy() ComputeResources {
targetComputeResource := make(ComputeResources)
diff --git a/internal/common/serve/spa.go b/internal/common/serve/spa.go
new file mode 100644
index 00000000000..30d9c654db6
--- /dev/null
+++ b/internal/common/serve/spa.go
@@ -0,0 +1,41 @@
+package serve
+
+import (
+ "errors"
+ "io/fs"
+ "net/http"
+ "strings"
+)
+
+const indexHTMLPage = "index.html"
+
+// SinglePageApplicationHandler handles requests for a single-page application front end. It prevents caching of
+// index.html responses and defers handling of file paths which cannot be found to the front end by serving index.html
+// in such cases.
+func SinglePageApplicationHandler(fsys http.FileSystem) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if shouldServeIndexHTML(fsys, r.URL.Path) {
+ r.URL.Path = "/"
+ // Prevent caching when serving index.html. Its content determines the version of the JS/CSS
+ // bundle, and we want to prevent the user from accessing a stale bundle.
+ w.Header().Set("Cache-Control", "no-store, must-revalidate")
+ }
+
+ http.FileServer(fsys).ServeHTTP(w, r)
+ })
+}
+
+func shouldServeIndexHTML(fsys http.FileSystem, urlPath string) bool {
+ trimmedURLPath := strings.TrimPrefix(urlPath, "/")
+
+ // Serve index.html when the file cannot be found - client-side routing in the SPA handles such cases.
+ if _, err := fsys.Open(trimmedURLPath); errors.Is(err, fs.ErrNotExist) {
+ return true
+ }
+
+ if trimmedURLPath == "" || trimmedURLPath == indexHTMLPage {
+ return true
+ }
+
+ return false
+}
diff --git a/internal/common/serve/static.go b/internal/common/serve/static.go
index 355ae05d8db..3c5a12bb3a5 100644
--- a/internal/common/serve/static.go
+++ b/internal/common/serve/static.go
@@ -1,7 +1,6 @@
package serve
import (
- "io/fs"
"net/http"
"github.com/pkg/errors"
@@ -9,27 +8,6 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
)
-// dirWithIndexFallback is a http.FileSystem that serves the index.html file at
-// the root of dir if the requested file is not found. This behavior differs
-// from http.Dir, which only forwards requests for /a/ to /a/index.html; we need
-// to serve the index.html file at the root of dir if the requested file is not
-// found, so that the frontend can handle routing in those cases.
-type dirWithIndexFallback struct {
- dir http.Dir
-}
-
-func CreateDirWithIndexFallback(path string) http.FileSystem {
- return dirWithIndexFallback{http.Dir(path)}
-}
-
-func (d dirWithIndexFallback) Open(name string) (http.File, error) {
- file, err := d.dir.Open(name)
- if errors.Is(err, fs.ErrNotExist) {
- return d.dir.Open("index.html")
- }
- return file, err
-}
-
// ListenAndServe calls server.ListenAndServe().
// Additionally, it calls server.Shutdown() if ctx is cancelled.
func ListenAndServe(ctx *armadacontext.Context, server *http.Server) error {
diff --git a/internal/executor/domain/resources.go b/internal/executor/domain/resources.go
index 4d00d3cd366..967d02d0070 100644
--- a/internal/executor/domain/resources.go
+++ b/internal/executor/domain/resources.go
@@ -14,11 +14,6 @@ func EmptyUtilisationData() *UtilisationData {
}
}
-func (a *UtilisationData) Max(b *UtilisationData) {
- a.CurrentUsage.Max(b.CurrentUsage)
- a.CumulativeUsage.Max(b.CumulativeUsage)
-}
-
func (u *UtilisationData) DeepCopy() *UtilisationData {
return &UtilisationData{
CurrentUsage: u.CurrentUsage.DeepCopy(),
@@ -29,3 +24,82 @@ func (u *UtilisationData) DeepCopy() *UtilisationData {
func (u *UtilisationData) IsEmpty() bool {
return len(u.CumulativeUsage) == 0 && len(u.CurrentUsage) == 0
}
+
+type UtilisationDataAggregation struct {
+ maxUsage armadaresource.ComputeResources
+ sumOfUsage armadaresource.ComputeResources
+ numDataPoints map[string]int64
+ cumulativeUsage armadaresource.ComputeResources
+}
+
+func EmptyUtilisationDataAggregation() *UtilisationDataAggregation {
+ return &UtilisationDataAggregation{
+ maxUsage: armadaresource.ComputeResources{},
+ sumOfUsage: armadaresource.ComputeResources{},
+ numDataPoints: map[string]int64{},
+ cumulativeUsage: armadaresource.ComputeResources{},
+ }
+}
+
+func NewUtilisationDataAggregation(u *UtilisationData) *UtilisationDataAggregation {
+ numDataPoints := make(map[string]int64)
+
+ for k := range u.CurrentUsage {
+ numDataPoints[k] = 1
+ }
+
+ return &UtilisationDataAggregation{
+ maxUsage: u.CurrentUsage.DeepCopy(),
+ sumOfUsage: u.CurrentUsage.DeepCopy(),
+ numDataPoints: numDataPoints,
+ cumulativeUsage: u.CumulativeUsage.DeepCopy(),
+ }
+}
+
+func (u *UtilisationDataAggregation) GetMaxUsage() armadaresource.ComputeResources {
+ return u.maxUsage
+}
+
+func (u *UtilisationDataAggregation) GetAvgUsage() armadaresource.ComputeResources {
+ avg := u.sumOfUsage.DeepCopy()
+ avg.Div(u.numDataPoints)
+ return avg
+}
+
+func (u *UtilisationDataAggregation) GetCumulativeUsage() armadaresource.ComputeResources {
+ return u.cumulativeUsage
+}
+
+func (a *UtilisationDataAggregation) Add(b *UtilisationData) {
+ a.maxUsage.Max(b.CurrentUsage)
+ a.sumOfUsage.Add(b.CurrentUsage)
+ a.cumulativeUsage.Max(b.CumulativeUsage)
+
+ for k := range b.CurrentUsage {
+ existing, ok := a.numDataPoints[k]
+ if ok {
+ a.numDataPoints[k] = existing + 1
+ } else {
+ a.numDataPoints[k] = 1
+ }
+ }
+}
+
+func (u *UtilisationDataAggregation) DeepCopy() *UtilisationDataAggregation {
+ numDataPoints := map[string]int64{}
+
+ for k, v := range u.numDataPoints {
+ numDataPoints[k] = v
+ }
+
+ return &UtilisationDataAggregation{
+ maxUsage: u.maxUsage.DeepCopy(),
+ sumOfUsage: u.sumOfUsage.DeepCopy(),
+ numDataPoints: numDataPoints,
+ cumulativeUsage: u.cumulativeUsage.DeepCopy(),
+ }
+}
+
+func (u *UtilisationDataAggregation) IsEmpty() bool {
+ return len(u.maxUsage) == 0
+}
diff --git a/internal/executor/domain/resources_test.go b/internal/executor/domain/resources_test.go
index 5ce50f7ab65..199becf7794 100644
--- a/internal/executor/domain/resources_test.go
+++ b/internal/executor/domain/resources_test.go
@@ -9,37 +9,76 @@ import (
armadaresource "github.com/armadaproject/armada/internal/common/resource"
)
-func TestUtilisationData_Max(t *testing.T) {
- data := &UtilisationData{
- CurrentUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("1"), "memory": resource.MustParse("10")},
- CumulativeUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("5")},
+func compareQuantityMaps(a, b map[string]resource.Quantity) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for key, aVal := range a {
+ bVal, exists := b[key]
+ if !exists {
+ return false
+ }
+ if aVal.String() != bVal.String() {
+ return false
+ }
+ }
+ return true
+}
+
+func TestUtilisationDataAggregation(t *testing.T) {
+ data := &UtilisationDataAggregation{
+ maxUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("1"), "memory": resource.MustParse("10")},
+ sumOfUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("1"), "memory": resource.MustParse("10")},
+ numDataPoints: map[string]int64{"cpu": 1, "memory": 1},
+ cumulativeUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("5")},
}
data2 := &UtilisationData{
CurrentUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("2"), "memory": resource.MustParse("1")},
CumulativeUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("10")},
}
- expected := &UtilisationData{
- CurrentUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("2"), "memory": resource.MustParse("10")},
- CumulativeUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("10")},
+ expected := &UtilisationDataAggregation{
+ maxUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("2"), "memory": resource.MustParse("10")},
+ sumOfUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("3"), "memory": resource.MustParse("11")},
+ numDataPoints: map[string]int64{"cpu": 2, "memory": 2},
+ cumulativeUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("10")},
}
- max := data
- max.Max(data2)
- assert.Equal(t, expected.CurrentUsage, max.CurrentUsage)
- assert.Equal(t, expected.CumulativeUsage, max.CumulativeUsage)
+ aggregated := data
+ aggregated.Add(data2)
+ assert.True(t, compareQuantityMaps(expected.maxUsage, aggregated.maxUsage))
+ assert.True(t, compareQuantityMaps(expected.sumOfUsage, aggregated.sumOfUsage))
+ assert.Equal(t, expected.numDataPoints, aggregated.numDataPoints)
+ assert.True(t, compareQuantityMaps(expected.cumulativeUsage, aggregated.cumulativeUsage))
}
-func TestUtilisationData_Max_WithEmpty(t *testing.T) {
+func TestUtilisationDataAggregation_WithEmpty(t *testing.T) {
currentUsage := armadaresource.ComputeResources{"cpu": resource.MustParse("1"), "memory": resource.MustParse("1")}
cumulativeUsage := armadaresource.ComputeResources{"cpu": resource.MustParse("10")}
data := &UtilisationData{
CurrentUsage: currentUsage.DeepCopy(),
CumulativeUsage: cumulativeUsage.DeepCopy(),
}
- max := EmptyUtilisationData()
- max.Max(data)
- assert.Equal(t, data.CurrentUsage, max.CurrentUsage)
- assert.Equal(t, data.CumulativeUsage, max.CumulativeUsage)
+ aggregated := EmptyUtilisationDataAggregation()
+ aggregated.Add(data)
+ assert.Equal(t, data.CurrentUsage, aggregated.maxUsage)
+ assert.Equal(t, data.CumulativeUsage, aggregated.cumulativeUsage)
+
+ assert.True(t, compareQuantityMaps(data.CurrentUsage, aggregated.maxUsage))
+ assert.True(t, compareQuantityMaps(data.CurrentUsage, aggregated.sumOfUsage))
+ assert.True(t, compareQuantityMaps(data.CumulativeUsage, aggregated.cumulativeUsage))
+}
+
+func TestUtilisationData_GetAvg(t *testing.T) {
+ data := &UtilisationDataAggregation{
+ maxUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("100m"), "memory": resource.MustParse("100Mi")},
+ sumOfUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("160m"), "memory": resource.MustParse("110Mi")},
+ numDataPoints: map[string]int64{"cpu": 2, "memory": 2},
+ cumulativeUsage: armadaresource.ComputeResources{"cpu": resource.MustParse("160m")},
+ }
+
+ expected := armadaresource.ComputeResources{"cpu": resource.MustParse("80m"), "memory": resource.MustParse("55Mi")}
+
+ assert.True(t, compareQuantityMaps(expected, data.GetAvgUsage()))
}
func TestUtilisationData_IsEmpty(t *testing.T) {
diff --git a/internal/executor/reporter/event.go b/internal/executor/reporter/event.go
index a11e954f47c..135a73017ab 100644
--- a/internal/executor/reporter/event.go
+++ b/internal/executor/reporter/event.go
@@ -318,7 +318,7 @@ func CreateReturnLeaseEvent(pod *v1.Pod, reason string, debugMessage string, clu
return sequence, nil
}
-func CreateJobUtilisationEvent(pod *v1.Pod, utilisationData *domain.UtilisationData, clusterId string) (*armadaevents.EventSequence, error) {
+func CreateJobUtilisationEvent(pod *v1.Pod, utilisationData *domain.UtilisationDataAggregation, clusterId string) (*armadaevents.EventSequence, error) {
sequence := createEmptySequence(pod)
jobId, runId, err := extractIds(pod)
if err != nil {
@@ -345,8 +345,9 @@ func CreateJobUtilisationEvent(pod *v1.Pod, utilisationData *domain.UtilisationD
},
},
},
- MaxResourcesForPeriod: utilisationData.CurrentUsage.ToProtoMap(),
- TotalCumulativeUsage: utilisationData.CumulativeUsage.ToProtoMap(),
+ MaxResourcesForPeriod: utilisationData.GetMaxUsage().ToProtoMap(),
+ AvgResourcesForPeriod: utilisationData.GetAvgUsage().ToProtoMap(),
+ TotalCumulativeUsage: utilisationData.GetCumulativeUsage().ToProtoMap(),
},
},
})
diff --git a/internal/executor/utilisation/job_utilisation_reporter.go b/internal/executor/utilisation/job_utilisation_reporter.go
index b4387db22bf..a044595a074 100644
--- a/internal/executor/utilisation/job_utilisation_reporter.go
+++ b/internal/executor/utilisation/job_utilisation_reporter.go
@@ -25,9 +25,9 @@ type UtilisationEventReporter struct {
}
type podUtilisationInfo struct {
- lastReported time.Time
- pod *v1.Pod
- utilisationMax *domain.UtilisationData
+ lastReported time.Time
+ pod *v1.Pod
+ aggregatedUtilisation *domain.UtilisationDataAggregation
}
func NewUtilisationEventReporter(
@@ -84,12 +84,12 @@ func (r *UtilisationEventReporter) ReportUtilisationEvents() {
reportingTime := now.Add(-r.reportingInterval)
for _, info := range r.podInfo {
currentUtilisation := r.podUtilisation.GetPodUtilisation(info.pod)
- info.utilisationMax.Max(currentUtilisation)
+ info.aggregatedUtilisation.Add(currentUtilisation)
if info.lastReported.Before(reportingTime) {
reported := r.reportUsage(info)
if reported {
info.lastReported = now
- info.utilisationMax = domain.EmptyUtilisationData()
+ info.aggregatedUtilisation = domain.EmptyUtilisationDataAggregation()
}
}
}
@@ -107,9 +107,9 @@ func (r *UtilisationEventReporter) updatePod(pod *v1.Pod) {
_, exists := r.podInfo[pod.Name]
if !exists {
r.podInfo[pod.Name] = &podUtilisationInfo{
- lastReported: time.Now(),
- pod: pod,
- utilisationMax: r.podUtilisation.GetPodUtilisation(pod),
+ lastReported: time.Now(),
+ pod: pod,
+ aggregatedUtilisation: domain.NewUtilisationDataAggregation(r.podUtilisation.GetPodUtilisation(pod)),
}
}
}
@@ -132,10 +132,10 @@ func (r *UtilisationEventReporter) deletePod(pod *v1.Pod) {
}
func (r *UtilisationEventReporter) reportUsage(info *podUtilisationInfo) bool {
- if info.utilisationMax.IsEmpty() {
+ if info.aggregatedUtilisation.IsEmpty() {
return false
}
- event, err := reporter.CreateJobUtilisationEvent(info.pod, info.utilisationMax, r.clusterContext.GetClusterId())
+ event, err := reporter.CreateJobUtilisationEvent(info.pod, info.aggregatedUtilisation, r.clusterContext.GetClusterId())
if err != nil {
log.Errorf("failed to create utilisation event %s", err)
return false
diff --git a/internal/executor/utilisation/job_utilisation_reporter_test.go b/internal/executor/utilisation/job_utilisation_reporter_test.go
index 39c23d5463d..aa70890b941 100644
--- a/internal/executor/utilisation/job_utilisation_reporter_test.go
+++ b/internal/executor/utilisation/job_utilisation_reporter_test.go
@@ -24,7 +24,7 @@ import (
var testPodResources = domain.UtilisationData{
CurrentUsage: armadaresource.ComputeResources{
- "cpu": resource.MustParse("1"),
+ "cpu": resource.MustParse("1000m"),
"memory": resource.MustParse("640Ki"),
},
CumulativeUsage: armadaresource.ComputeResources{
@@ -62,6 +62,7 @@ func TestUtilisationEventReporter_ReportUtilisationEvents(t *testing.T) {
assert.True(t, ok)
assert.Equal(t, testPodResources.CurrentUsage, armadaresource.FromProtoMap(event1.ResourceUtilisation.MaxResourcesForPeriod))
+ assert.Equal(t, testPodResources.CurrentUsage, armadaresource.FromProtoMap(event1.ResourceUtilisation.AvgResourcesForPeriod))
assert.Equal(t, testPodResources.CumulativeUsage, armadaresource.FromProtoMap(event1.ResourceUtilisation.TotalCumulativeUsage))
event1CreatedTime := fakeEventReporter.ReceivedEvents[0].Event.Events[0].Created
diff --git a/internal/executor/utilisation/pod_utilisation.go b/internal/executor/utilisation/pod_utilisation.go
index ec075b198e8..a95c4dccdaf 100644
--- a/internal/executor/utilisation/pod_utilisation.go
+++ b/internal/executor/utilisation/pod_utilisation.go
@@ -8,7 +8,6 @@ import (
v1 "k8s.io/api/core/v1"
log "github.com/armadaproject/armada/internal/common/logging"
- armadaresource "github.com/armadaproject/armada/internal/common/resource"
commonUtil "github.com/armadaproject/armada/internal/common/util"
"github.com/armadaproject/armada/internal/executor/configuration"
clusterContext "github.com/armadaproject/armada/internal/executor/context"
@@ -115,10 +114,7 @@ func (q *PodUtilisationServiceImpl) RefreshUtilisationData() {
podNameToUtilisationData := map[string]*domain.UtilisationData{}
for _, podName := range podNames {
- podNameToUtilisationData[podName] = &domain.UtilisationData{
- CurrentUsage: armadaresource.ComputeResources{},
- CumulativeUsage: armadaresource.ComputeResources{},
- }
+ podNameToUtilisationData[podName] = domain.EmptyUtilisationData()
}
for _, fetcher := range q.fetchers {
diff --git a/internal/lookoutv2/application.go b/internal/lookout/application.go
similarity index 93%
rename from internal/lookoutv2/application.go
rename to internal/lookout/application.go
index ec6dbf6b10e..c891423017e 100644
--- a/internal/lookoutv2/application.go
+++ b/internal/lookout/application.go
@@ -1,6 +1,6 @@
//go:generate go run ./generate/main.go
-package lookoutv2
+package lookout
import (
"github.com/IBM/pgxpoolprometheus"
@@ -15,14 +15,14 @@ import (
"github.com/armadaproject/armada/internal/common/database"
"github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/slices"
- "github.com/armadaproject/armada/internal/lookoutv2/configuration"
- "github.com/armadaproject/armada/internal/lookoutv2/conversions"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/restapi"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/restapi/operations"
- "github.com/armadaproject/armada/internal/lookoutv2/repository"
+ "github.com/armadaproject/armada/internal/lookout/configuration"
+ "github.com/armadaproject/armada/internal/lookout/conversions"
+ "github.com/armadaproject/armada/internal/lookout/gen/restapi"
+ "github.com/armadaproject/armada/internal/lookout/gen/restapi/operations"
+ "github.com/armadaproject/armada/internal/lookout/repository"
)
-func Serve(configuration configuration.LookoutV2Config) error {
+func Serve(configuration configuration.LookoutConfig) error {
// load embedded swagger file
swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
if err != nil {
diff --git a/internal/lookoutv2/configuration/types.go b/internal/lookout/configuration/types.go
similarity index 98%
rename from internal/lookoutv2/configuration/types.go
rename to internal/lookout/configuration/types.go
index eb3ebfb77d1..3d92219cfa6 100644
--- a/internal/lookoutv2/configuration/types.go
+++ b/internal/lookout/configuration/types.go
@@ -7,7 +7,7 @@ import (
"github.com/armadaproject/armada/internal/server/configuration"
)
-type LookoutV2Config struct {
+type LookoutConfig struct {
ApiPort int
Profiling *profilingconfig.ProfilingConfig
MetricsPort int
diff --git a/internal/lookoutv2/configuration/validation.go b/internal/lookout/configuration/validation.go
similarity index 74%
rename from internal/lookoutv2/configuration/validation.go
rename to internal/lookout/configuration/validation.go
index e9228dbbef2..7e3f173e63e 100644
--- a/internal/lookoutv2/configuration/validation.go
+++ b/internal/lookout/configuration/validation.go
@@ -2,7 +2,7 @@ package configuration
import "github.com/go-playground/validator/v10"
-func (c LookoutV2Config) Validate() error {
+func (c LookoutConfig) Validate() error {
validate := validator.New()
return validate.Struct(c)
}
diff --git a/internal/lookoutv2/conversions/convert.go b/internal/lookout/conversions/convert.go
similarity index 92%
rename from internal/lookoutv2/conversions/convert.go
rename to internal/lookout/conversions/convert.go
index 826aee76ccc..a427b48e88e 100644
--- a/internal/lookoutv2/conversions/convert.go
+++ b/internal/lookout/conversions/convert.go
@@ -6,9 +6,9 @@ import (
"github.com/go-openapi/strfmt"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/restapi/operations"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/restapi/operations"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
func ToSwaggerJob(job *model.Job) *models.Job {
@@ -37,6 +37,7 @@ func ToSwaggerJob(job *model.Job) *models.Job {
State: job.State,
Submitted: strfmt.DateTime(job.Submitted),
CancelReason: job.CancelReason,
+ CancelUser: job.CancelUser,
Node: job.Node,
Cluster: job.Cluster,
ExitCode: job.ExitCode,
diff --git a/internal/lookoutv2/conversions/convert_test.go b/internal/lookout/conversions/convert_test.go
similarity index 96%
rename from internal/lookoutv2/conversions/convert_test.go
rename to internal/lookout/conversions/convert_test.go
index c14ce732a90..8572bedd80c 100644
--- a/internal/lookoutv2/conversions/convert_test.go
+++ b/internal/lookout/conversions/convert_test.go
@@ -9,8 +9,8 @@ import (
"k8s.io/utils/pointer"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
var (
diff --git a/internal/lookout/dbloadtester/queries.go b/internal/lookout/dbloadtester/queries.go
new file mode 100644
index 00000000000..c63299bf0eb
--- /dev/null
+++ b/internal/lookout/dbloadtester/queries.go
@@ -0,0 +1,273 @@
+package dbloadtester
+
+var getJobByID = `
+SELECT
+ selected_jobs.job_id,
+ selected_jobs.queue,
+ selected_jobs.owner,
+ selected_jobs.namespace,
+ selected_jobs.jobset,
+ selected_jobs.cpu,
+ selected_jobs.memory,
+ selected_jobs.ephemeral_storage,
+ selected_jobs.gpu,
+ selected_jobs.priority,
+ selected_jobs.submitted,
+ selected_jobs.cancelled,
+ selected_jobs.state,
+ selected_jobs.last_transition_time,
+ selected_jobs.duplicate,
+ selected_jobs.priority_class,
+ selected_jobs.latest_run_id,
+ selected_jobs.cancel_reason,
+ selected_jobs.annotations,
+ selected_runs.runs
+FROM (
+ SELECT *
+ FROM job AS j
+ WHERE j.job_id = $1
+ ORDER BY j.job_id DESC
+ OFFSET 0 LIMIT 50
+ ) AS selected_jobs
+ CROSS JOIN LATERAL (
+ SELECT
+ COALESCE(
+ json_agg(
+ json_strip_nulls(
+ json_build_object(
+ 'runId', run_id,
+ 'cluster', cluster,
+ 'node', node,
+ 'leased', leased AT TIME ZONE 'UTC',
+ 'pending', pending AT TIME ZONE 'UTC',
+ 'started', started AT TIME ZONE 'UTC',
+ 'finished', finished AT TIME ZONE 'UTC',
+ 'jobRunState', job_run_state,
+ 'exitCode', exit_code
+ )
+ )
+ ORDER BY COALESCE(leased, pending)
+ ) FILTER (WHERE run_id IS NOT NULL),
+ '[]'
+ ) AS runs
+ FROM job_run
+ WHERE job_id = selected_jobs.job_id
+ ) AS selected_runs
+`
+
+var getLookoutFrontPage = `
+SELECT
+ selected_jobs.job_id,
+ selected_jobs.queue,
+ selected_jobs.owner,
+ selected_jobs.namespace,
+ selected_jobs.jobset,
+ selected_jobs.cpu,
+ selected_jobs.memory,
+ selected_jobs.ephemeral_storage,
+ selected_jobs.gpu,
+ selected_jobs.priority,
+ selected_jobs.submitted,
+ selected_jobs.cancelled,
+ selected_jobs.state,
+ selected_jobs.last_transition_time,
+ selected_jobs.duplicate,
+ selected_jobs.priority_class,
+ selected_jobs.latest_run_id,
+ selected_jobs.cancel_reason,
+ selected_jobs.annotations,
+ selected_runs.runs
+FROM (
+ SELECT *
+ FROM job AS j
+ ORDER BY j.submitted DESC
+ OFFSET 0 LIMIT 100
+ ) AS selected_jobs
+ CROSS JOIN LATERAL (
+ SELECT
+ COALESCE(
+ json_agg(
+ json_strip_nulls(
+ json_build_object(
+ 'runId', run_id,
+ 'cluster', cluster,
+ 'node', node,
+ 'leased', leased AT TIME ZONE 'UTC',
+ 'pending', pending AT TIME ZONE 'UTC',
+ 'started', started AT TIME ZONE 'UTC',
+ 'finished', finished AT TIME ZONE 'UTC',
+ 'jobRunState', job_run_state,
+ 'exitCode', exit_code
+ )
+ )
+ ORDER BY COALESCE(leased, pending)
+ ) FILTER (WHERE run_id IS NOT NULL),
+ '[]'
+ ) AS runs
+ FROM job_run
+ WHERE job_id = selected_jobs.job_id
+ ) AS selected_runs;
+`
+
+var getQueueActiveJobsets = `
+SELECT j.jobset,
+ COUNT(*) as count,
+ SUM(CASE WHEN j.state = 1 THEN 1 ELSE 0 END) AS state_QUEUED,
+ SUM(CASE WHEN j.state = 2 THEN 1 ELSE 0 END) AS state_PENDING,
+ SUM(CASE WHEN j.state = 3 THEN 1 ELSE 0 END) AS state_RUNNING,
+ SUM(CASE WHEN j.state = 4 THEN 1 ELSE 0 END) AS state_SUCCEEDED,
+ SUM(CASE WHEN j.state = 5 THEN 1 ELSE 0 END) AS state_FAILED,
+ SUM(CASE WHEN j.state = 6 THEN 1 ELSE 0 END) AS state_CANCELLED,
+ SUM(CASE WHEN j.state = 7 THEN 1 ELSE 0 END) AS state_PREEMPTED,
+ SUM(CASE WHEN j.state = 8 THEN 1 ELSE 0 END) AS state_LEASED,
+ SUM(CASE WHEN j.state = 9 THEN 1 ELSE 0 END) AS state_REJECTED,
+ MIN(j.submitted) AS submitted
+FROM job AS j
+ INNER JOIN (SELECT DISTINCT queue, jobset
+ FROM job
+ WHERE state IN (1, 2, 3, 8)) AS active_job_sets USING (queue, jobset)
+WHERE queue = $1
+GROUP BY j.jobset
+ORDER BY submitted DESC
+OFFSET 0;
+`
+
+var getQueueAllJobs = `
+SELECT j.jobset,
+ COUNT(*) as count,
+ SUM(CASE WHEN j.state = 1 THEN 1 ELSE 0 END) AS state_QUEUED,
+ SUM(CASE WHEN j.state = 2 THEN 1 ELSE 0 END) AS state_PENDING,
+ SUM(CASE WHEN j.state = 3 THEN 1 ELSE 0 END) AS state_RUNNING,
+ SUM(CASE WHEN j.state = 4 THEN 1 ELSE 0 END) AS state_SUCCEEDED,
+ SUM(CASE WHEN j.state = 5 THEN 1 ELSE 0 END) AS state_FAILED,
+ SUM(CASE WHEN j.state = 6 THEN 1 ELSE 0 END) AS state_CANCELLED,
+ SUM(CASE WHEN j.state = 7 THEN 1 ELSE 0 END) AS state_PREEMPTED,
+ SUM(CASE WHEN j.state = 8 THEN 1 ELSE 0 END) AS state_LEASED,
+ SUM(CASE WHEN j.state = 9 THEN 1 ELSE 0 END) AS state_REJECTED,
+ MIN(j.submitted) AS submitted
+FROM job AS j
+WHERE queue = $1
+GROUP BY j.jobset
+ORDER BY submitted DESC
+OFFSET 0;
+`
+
+var getJobsetGroupedByState = `
+SELECT j.state,
+ COUNT(*) as count,
+ MIN(j.submitted) AS submitted,
+ AVG(j.last_transition_time_seconds) AS last_transition_time_seconds
+FROM job AS j
+WHERE j.jobset = $1
+GROUP BY j.state
+ORDER BY count DESC
+OFFSET 0;
+`
+
+var getJobsRunningInQueue = `
+SELECT
+ selected_jobs.job_id,
+ selected_jobs.queue,
+ selected_jobs.owner,
+ selected_jobs.namespace,
+ selected_jobs.jobset,
+ selected_jobs.cpu,
+ selected_jobs.memory,
+ selected_jobs.ephemeral_storage,
+ selected_jobs.gpu,
+ selected_jobs.priority,
+ selected_jobs.submitted,
+ selected_jobs.cancelled,
+ selected_jobs.state,
+ selected_jobs.last_transition_time,
+ selected_jobs.duplicate,
+ selected_jobs.priority_class,
+ selected_jobs.latest_run_id,
+ selected_jobs.cancel_reason,
+ selected_jobs.annotations,
+ selected_runs.runs
+FROM (
+ SELECT *
+ FROM job AS j
+ WHERE j.queue = $1 AND j.state = 3
+ ORDER BY j.job_id DESC
+ ) AS selected_jobs
+ CROSS JOIN LATERAL (
+ SELECT
+ COALESCE(
+ json_agg(
+ json_strip_nulls(
+ json_build_object(
+ 'runId', run_id,
+ 'cluster', cluster,
+ 'node', node,
+ 'leased', leased AT TIME ZONE 'UTC',
+ 'pending', pending AT TIME ZONE 'UTC',
+ 'started', started AT TIME ZONE 'UTC',
+ 'finished', finished AT TIME ZONE 'UTC',
+ 'jobRunState', job_run_state,
+ 'exitCode', exit_code
+ )
+ )
+ ORDER BY COALESCE(leased, pending)
+ ) FILTER (WHERE run_id IS NOT NULL),
+ '[]'
+ ) AS runs
+ FROM job_run
+ WHERE job_id = selected_jobs.job_id
+ ) AS selected_runs;
+`
+
+var getJobsRunningInQueueOrderBySubmitted = `
+SELECT
+ selected_jobs.job_id,
+ selected_jobs.queue,
+ selected_jobs.owner,
+ selected_jobs.namespace,
+ selected_jobs.jobset,
+ selected_jobs.cpu,
+ selected_jobs.memory,
+ selected_jobs.ephemeral_storage,
+ selected_jobs.gpu,
+ selected_jobs.priority,
+ selected_jobs.submitted,
+ selected_jobs.cancelled,
+ selected_jobs.state,
+ selected_jobs.last_transition_time,
+ selected_jobs.duplicate,
+ selected_jobs.priority_class,
+ selected_jobs.latest_run_id,
+ selected_jobs.cancel_reason,
+ selected_jobs.annotations,
+ selected_runs.runs
+FROM (
+ SELECT *
+ FROM job AS j
+ WHERE j.queue = $1 AND j.state = 3
+ ORDER BY j.submitted DESC LIMIT 100 OFFSET 0
+ ) AS selected_jobs
+ CROSS JOIN LATERAL (
+ SELECT
+ COALESCE(
+ json_agg(
+ json_strip_nulls(
+ json_build_object(
+ 'runId', run_id,
+ 'cluster', cluster,
+ 'node', node,
+ 'leased', leased AT TIME ZONE 'UTC',
+ 'pending', pending AT TIME ZONE 'UTC',
+ 'started', started AT TIME ZONE 'UTC',
+ 'finished', finished AT TIME ZONE 'UTC',
+ 'jobRunState', job_run_state,
+ 'exitCode', exit_code
+ )
+ )
+ ORDER BY COALESCE(leased, pending)
+ ) FILTER (WHERE run_id IS NOT NULL),
+ '[]'
+ ) AS runs
+ FROM job_run
+ WHERE job_id = selected_jobs.job_id
+ ) AS selected_runs;
+`
diff --git a/internal/lookout/dbloadtester/queryer.go b/internal/lookout/dbloadtester/queryer.go
new file mode 100644
index 00000000000..6c1d60c9b02
--- /dev/null
+++ b/internal/lookout/dbloadtester/queryer.go
@@ -0,0 +1,312 @@
+package dbloadtester
+
+import (
+ "fmt"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/jackc/pgx/v5"
+ "github.com/jackc/pgx/v5/pgxpool"
+
+ "github.com/armadaproject/armada/internal/common/armadacontext"
+ "github.com/armadaproject/armada/internal/common/database"
+ log "github.com/armadaproject/armada/internal/common/logging"
+ "github.com/armadaproject/armada/internal/lookout/configuration"
+)
+
+type ReadTestConfig struct {
+ Queues []any
+ Jobsets []any
+ Ids []any
+ QueueCounts map[string]int64
+ JobsetCounts map[string]int64
+}
+
+func (r ReadTestConfig) Validate() error {
+ return nil
+}
+
+var queryToSummaryName = map[string]string{
+ getJobByID: "getJobByID",
+ getLookoutFrontPage: "getLookoutFrontPage",
+ getQueueActiveJobsets: "getQueueActiveJobsets",
+ getQueueAllJobs: "getQueueAllJobs",
+ getJobsRunningInQueue: "getJobsRunningInQueue",
+ getJobsetGroupedByState: "getJobsetGroupedByState",
+ getJobsRunningInQueueOrderBySubmitted: "getJobsRunningInQueueOrderBySubmitted",
+}
+
+type QueryWithParams struct {
+ Query string
+ Arguments []any
+}
+
+var filterTypeToQueryMap = map[string][]string{
+ "queue": {
+ getQueueActiveJobsets,
+ getQueueAllJobs,
+ getJobsRunningInQueue,
+ getJobsRunningInQueueOrderBySubmitted,
+ },
+ "jobset": {
+ getJobsetGroupedByState,
+ },
+ "id": {
+ getJobByID,
+ },
+ "none": {
+ getLookoutFrontPage,
+ },
+}
+
+var parallelism = 2
+
+func DoQueries(config configuration.LookoutConfig, readConfig ReadTestConfig, ctx *armadacontext.Context) (string, error) {
+ db, err := database.OpenPgxPool(config.Postgres)
+ if err != nil {
+ return "", err
+ }
+
+ filterTypeToArgs := map[string][]any{
+ "none": {nil},
+ "queue": readConfig.Queues,
+ "jobset": readConfig.Jobsets,
+ "id": readConfig.Ids,
+ }
+
+ queryTotalDuration := map[string]time.Duration{}
+ queryTotalRows := map[string]int64{}
+ queryTotal := map[string]int64{}
+
+ ch := make(chan *QueryWithParams)
+
+ queryPool := []*queryer{}
+ for i := 0; i < parallelism; i++ {
+ queryPool = append(queryPool, &queryer{
+ db,
+ ctx,
+ map[string]time.Duration{},
+ map[string]int64{},
+ nil,
+ })
+ }
+
+ var wg sync.WaitGroup
+ for _, queryer := range queryPool {
+ wg.Add(1)
+
+ go func() {
+ defer wg.Done()
+ queryer.paralleliseQueries(ch)
+ }()
+ }
+
+ for filterType, args := range filterTypeToArgs {
+ for _, arg := range args {
+ for _, query := range filterTypeToQueryMap[filterType] {
+ if arg == nil {
+ ch <- &QueryWithParams{query, []any{}}
+ } else {
+ ch <- &QueryWithParams{query, []any{arg}}
+ }
+ }
+ }
+ }
+ close(ch)
+ wg.Wait()
+
+ for _, queryer := range queryPool {
+ for query, duration := range queryer.queryTotalDuration {
+ queryTotalDuration[query] += duration
+ queryTotal[query] += 1
+ }
+
+ for query, rows := range queryer.queryTotalRows {
+ queryTotalRows[query] += rows
+ }
+ }
+
+ reportLines := []string{}
+
+ for k, v := range queryTotalDuration {
+ reportLines = append(
+ reportLines,
+ fmt.Sprintf("%s: Total Duration: %s - Total Rows Returned: %d, Average Duration: %s",
+ queryToSummaryName[k],
+ v.String(),
+ queryTotalRows[k],
+ (v/time.Duration(queryTotal[k])).String(),
+ ),
+ )
+ }
+
+ jobsetCounts, err := queryPool[0].reportJobsetCount(filterTypeToArgs["jobset"], readConfig.JobsetCounts)
+ if err != nil {
+ return "", err
+ }
+
+ queueCounts, err := queryPool[0].reportQueueCount(filterTypeToArgs["queue"], readConfig.QueueCounts)
+ if err != nil {
+ return "", err
+ }
+
+ var totalQueueCounts int64
+ for _, v := range queueCounts {
+ totalQueueCounts += v
+ }
+
+ var totalJobsetCounts int64
+ for _, v := range jobsetCounts {
+ totalJobsetCounts += v
+ }
+
+ reportLines = append(
+ reportLines,
+ fmt.Sprintf("\nTotal Queues queried: %d", len(filterTypeToArgs["queue"])),
+ fmt.Sprintf("Total IDs queried: %d", len(filterTypeToArgs["id"])),
+ fmt.Sprintf("Total Jobsets queried: %d", len(filterTypeToArgs["jobset"])),
+ fmt.Sprintf("Total Rows of Queues: %d, Total Rows of Jobsets: %d",
+ totalQueueCounts,
+ totalJobsetCounts,
+ ),
+ )
+
+ return strings.Join(reportLines, "\n"), err
+}
+
+type queryer struct {
+ db *pgxpool.Pool
+ ctx *armadacontext.Context
+ queryTotalDuration map[string]time.Duration
+ queryTotalRows map[string]int64
+ err error
+}
+
+func (q *queryer) reportJobsetCount(jobsets []any, precalculated map[string]int64) (map[string]int64, error) {
+ jobsetToCount := map[string]int64{}
+ for _, jobset := range jobsets {
+ if _, ok := precalculated[jobset.(string)]; ok {
+ jobsetToCount[jobset.(string)] = precalculated[jobset.(string)]
+ continue
+ }
+
+ log.Infof("Counting rows available to be queried with jobset: %s", jobset)
+ rows, err := q.db.Query(
+ q.ctx,
+ `SELECT COUNT(*)
+ FROM job as j
+ WHERE j.jobset = $1`,
+ jobset,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to query jobset rows: %v", err)
+ }
+
+ var rowCount int64
+ if rows.Next() {
+ err = rows.Scan(&rowCount)
+ if err != nil {
+ return nil, fmt.Errorf("failed to count jobset rows: %v", err)
+ }
+ }
+ rows.Close()
+
+ jobsetToCount[jobset.(string)] = rowCount
+ }
+
+ return jobsetToCount, nil
+}
+
+func (q *queryer) reportQueueCount(queues []any, precalculated map[string]int64) (map[string]int64, error) {
+ queueToCount := map[string]int64{}
+ for _, queue := range queues {
+ if _, ok := precalculated[queue.(string)]; ok {
+ queueToCount[queue.(string)] = precalculated[queue.(string)]
+ continue
+ }
+
+ log.Infof("Counting rows available to be queried with queue: %s", queue)
+ rows, err := q.db.Query(
+ q.ctx,
+ `SELECT COUNT(*)
+ FROM job as j
+ WHERE j.queue = $1`,
+ queue,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to query queue rows: %v", err)
+ }
+
+ var rowCount int64
+ if rows.Next() {
+ err = rows.Scan(&rowCount)
+ if err != nil {
+ return nil, fmt.Errorf("failed to count queue rows: %v", err)
+ }
+ }
+ rows.Close()
+
+ queueToCount[queue.(string)] = rowCount
+ }
+
+ return queueToCount, nil
+}
+
+func (q *queryer) paralleliseQueries(ch chan *QueryWithParams) {
+ for queryWithArgs := range ch {
+ duration, rows, err := doQuery(q.db, q.ctx, queryWithArgs.Query, queryWithArgs.Arguments)
+ if err != nil {
+ q.err = err
+ return
+ }
+ q.queryTotalRows[queryWithArgs.Query] += rows
+ q.queryTotalDuration[queryWithArgs.Query] += duration
+ log.Infof("Query Type: %s, Query Duration: %s, Rows Returned: %d", queryToSummaryName[queryWithArgs.Query], duration.String(), rows)
+ }
+
+ return
+}
+
+func doQuery(db *pgxpool.Pool, ctx *armadacontext.Context, query string, args []any) (queryDuration time.Duration, rowsReturned int64, err error) {
+ var startTime time.Time
+ startTimeFunc := func(rows pgx.Row) error {
+ return rows.Scan(&startTime)
+ }
+
+ var endTime time.Time
+ endTimeFunc := func(rows pgx.Row) error {
+ return rows.Scan(&endTime)
+ }
+
+ var totalRows int64
+ totalRowFunc := func(rows pgx.Rows) error {
+ for rows.Next() {
+ totalRows += 1
+ }
+ return nil
+ }
+ tx, err := db.BeginTx(ctx, pgx.TxOptions{})
+ if err != nil {
+ return 0, 0, err
+ }
+
+ log.Infof("Beginning query of type with args: %s, %v", queryToSummaryName[query], args)
+
+ batch := &pgx.Batch{}
+ batch.Queue("SELECT clock_timestamp()").QueryRow(startTimeFunc)
+ batch.Queue(query, args...).Query(totalRowFunc)
+ batch.Queue("SELECT clock_timestamp()").QueryRow(endTimeFunc)
+ err = tx.SendBatch(ctx, batch).Close()
+ if err != nil {
+ return 0, 0, err
+ }
+
+ if tx.Commit(ctx) != nil {
+ return 0, 0, err
+ }
+
+ duration := endTime.Sub(startTime)
+
+ return duration, totalRows, nil
+}
diff --git a/internal/lookoutv2/gen/models/debug_message.go b/internal/lookout/gen/models/debug_message.go
similarity index 100%
rename from internal/lookoutv2/gen/models/debug_message.go
rename to internal/lookout/gen/models/debug_message.go
diff --git a/internal/lookoutv2/gen/models/error.go b/internal/lookout/gen/models/error.go
similarity index 100%
rename from internal/lookoutv2/gen/models/error.go
rename to internal/lookout/gen/models/error.go
diff --git a/internal/lookoutv2/gen/models/filter.go b/internal/lookout/gen/models/filter.go
similarity index 100%
rename from internal/lookoutv2/gen/models/filter.go
rename to internal/lookout/gen/models/filter.go
diff --git a/internal/lookoutv2/gen/models/group.go b/internal/lookout/gen/models/group.go
similarity index 100%
rename from internal/lookoutv2/gen/models/group.go
rename to internal/lookout/gen/models/group.go
diff --git a/internal/lookoutv2/gen/models/job.go b/internal/lookout/gen/models/job.go
similarity index 99%
rename from internal/lookoutv2/gen/models/job.go
rename to internal/lookout/gen/models/job.go
index 203beaf9af5..c1e2dc9dbbe 100644
--- a/internal/lookoutv2/gen/models/job.go
+++ b/internal/lookout/gen/models/job.go
@@ -28,6 +28,9 @@ type Job struct {
// cancel reason
CancelReason *string `json:"cancelReason,omitempty"`
+ // cancel user
+ CancelUser *string `json:"cancelUser,omitempty"`
+
// cancelled
// Format: date-time
Cancelled *strfmt.DateTime `json:"cancelled,omitempty"`
diff --git a/internal/lookoutv2/gen/models/order.go b/internal/lookout/gen/models/order.go
similarity index 100%
rename from internal/lookoutv2/gen/models/order.go
rename to internal/lookout/gen/models/order.go
diff --git a/internal/lookoutv2/gen/models/run.go b/internal/lookout/gen/models/run.go
similarity index 100%
rename from internal/lookoutv2/gen/models/run.go
rename to internal/lookout/gen/models/run.go
diff --git a/internal/lookoutv2/gen/restapi/configure_lookout.go b/internal/lookout/gen/restapi/configure_lookout.go
similarity index 85%
rename from internal/lookoutv2/gen/restapi/configure_lookout.go
rename to internal/lookout/gen/restapi/configure_lookout.go
index 98b606c5d3e..38307e4234e 100644
--- a/internal/lookoutv2/gen/restapi/configure_lookout.go
+++ b/internal/lookout/gen/restapi/configure_lookout.go
@@ -15,9 +15,9 @@ import (
"golang.org/x/exp/slices"
"github.com/armadaproject/armada/internal/common/serve"
- "github.com/armadaproject/armada/internal/lookoutv2/configuration"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/restapi/operations"
- "github.com/armadaproject/armada/internal/lookoutv2/metrics"
+ "github.com/armadaproject/armada/internal/lookout/configuration"
+ "github.com/armadaproject/armada/internal/lookout/gen/restapi/operations"
+ "github.com/armadaproject/armada/internal/lookout/metrics"
)
//go:generate swagger generate server --target ../../gen --name Lookout --spec ../../swagger.yaml --principal interface{} --exclude-main
@@ -97,7 +97,7 @@ func setupGlobalMiddleware(apiHandler http.Handler) http.Handler {
func uiHandler(apiHandler http.Handler) http.Handler {
mux := http.NewServeMux()
- mux.Handle("/", setCacheControl(http.FileServer(serve.CreateDirWithIndexFallback("./internal/lookoutui/build"))))
+ mux.Handle("/", serve.SinglePageApplicationHandler(http.Dir("./internal/lookoutui/build")))
mux.HandleFunc("/config", func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
@@ -112,19 +112,6 @@ func uiHandler(apiHandler http.Handler) http.Handler {
return mux
}
-func setCacheControl(fileHandler http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.Path == "/" || r.URL.Path == "/index.html" {
- // Because the version of index.html determines the version of the
- // JavaScript bundle, caching index.html would prevent users from
- // ever picking up new versions of the JavaScript bundle without
- // manually invalidating the cache.
- w.Header().Set("Cache-Control", "no-store")
- }
- fileHandler.ServeHTTP(w, r)
- })
-}
-
func allowCORS(handler http.Handler, corsAllowedOrigins []string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if origin := r.Header.Get("Origin"); origin != "" && slices.Contains(corsAllowedOrigins, origin) {
diff --git a/internal/lookoutv2/gen/restapi/doc.go b/internal/lookout/gen/restapi/doc.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/doc.go
rename to internal/lookout/gen/restapi/doc.go
diff --git a/internal/lookoutv2/gen/restapi/embedded_spec.go b/internal/lookout/gen/restapi/embedded_spec.go
similarity index 99%
rename from internal/lookoutv2/gen/restapi/embedded_spec.go
rename to internal/lookout/gen/restapi/embedded_spec.go
index 3edcd568f06..a5f3e8c363d 100644
--- a/internal/lookoutv2/gen/restapi/embedded_spec.go
+++ b/internal/lookout/gen/restapi/embedded_spec.go
@@ -586,6 +586,10 @@ func init() {
"type": "string",
"x-nullable": true
},
+ "cancelUser": {
+ "type": "string",
+ "x-nullable": true
+ },
"cancelled": {
"type": "string",
"format": "date-time",
@@ -1408,6 +1412,10 @@ func init() {
"type": "string",
"x-nullable": true
},
+ "cancelUser": {
+ "type": "string",
+ "x-nullable": true
+ },
"cancelled": {
"type": "string",
"format": "date-time",
diff --git a/internal/lookoutv2/gen/restapi/operations/get_health.go b/internal/lookout/gen/restapi/operations/get_health.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_health.go
rename to internal/lookout/gen/restapi/operations/get_health.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_health_parameters.go b/internal/lookout/gen/restapi/operations/get_health_parameters.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_health_parameters.go
rename to internal/lookout/gen/restapi/operations/get_health_parameters.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_health_responses.go b/internal/lookout/gen/restapi/operations/get_health_responses.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_health_responses.go
rename to internal/lookout/gen/restapi/operations/get_health_responses.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_health_urlbuilder.go b/internal/lookout/gen/restapi/operations/get_health_urlbuilder.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_health_urlbuilder.go
rename to internal/lookout/gen/restapi/operations/get_health_urlbuilder.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_error.go b/internal/lookout/gen/restapi/operations/get_job_error.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_error.go
rename to internal/lookout/gen/restapi/operations/get_job_error.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_error_parameters.go b/internal/lookout/gen/restapi/operations/get_job_error_parameters.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_error_parameters.go
rename to internal/lookout/gen/restapi/operations/get_job_error_parameters.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_error_responses.go b/internal/lookout/gen/restapi/operations/get_job_error_responses.go
similarity index 98%
rename from internal/lookoutv2/gen/restapi/operations/get_job_error_responses.go
rename to internal/lookout/gen/restapi/operations/get_job_error_responses.go
index 7a8ca53ce9f..40ae664a0ec 100644
--- a/internal/lookoutv2/gen/restapi/operations/get_job_error_responses.go
+++ b/internal/lookout/gen/restapi/operations/get_job_error_responses.go
@@ -10,7 +10,7 @@ import (
"github.com/go-openapi/runtime"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GetJobErrorOKCode is the HTTP code returned for type GetJobErrorOK
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_error_urlbuilder.go b/internal/lookout/gen/restapi/operations/get_job_error_urlbuilder.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_error_urlbuilder.go
rename to internal/lookout/gen/restapi/operations/get_job_error_urlbuilder.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message.go b/internal/lookout/gen/restapi/operations/get_job_run_debug_message.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message.go
rename to internal/lookout/gen/restapi/operations/get_job_run_debug_message.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message_parameters.go b/internal/lookout/gen/restapi/operations/get_job_run_debug_message_parameters.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message_parameters.go
rename to internal/lookout/gen/restapi/operations/get_job_run_debug_message_parameters.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message_responses.go b/internal/lookout/gen/restapi/operations/get_job_run_debug_message_responses.go
similarity index 98%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message_responses.go
rename to internal/lookout/gen/restapi/operations/get_job_run_debug_message_responses.go
index 1e8082c2b77..ba9315e9b5f 100644
--- a/internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message_responses.go
+++ b/internal/lookout/gen/restapi/operations/get_job_run_debug_message_responses.go
@@ -10,7 +10,7 @@ import (
"github.com/go-openapi/runtime"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GetJobRunDebugMessageOKCode is the HTTP code returned for type GetJobRunDebugMessageOK
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message_urlbuilder.go b/internal/lookout/gen/restapi/operations/get_job_run_debug_message_urlbuilder.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_debug_message_urlbuilder.go
rename to internal/lookout/gen/restapi/operations/get_job_run_debug_message_urlbuilder.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_error.go b/internal/lookout/gen/restapi/operations/get_job_run_error.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_error.go
rename to internal/lookout/gen/restapi/operations/get_job_run_error.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_error_parameters.go b/internal/lookout/gen/restapi/operations/get_job_run_error_parameters.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_error_parameters.go
rename to internal/lookout/gen/restapi/operations/get_job_run_error_parameters.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_error_responses.go b/internal/lookout/gen/restapi/operations/get_job_run_error_responses.go
similarity index 98%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_error_responses.go
rename to internal/lookout/gen/restapi/operations/get_job_run_error_responses.go
index e8a17e5b37d..31f74687753 100644
--- a/internal/lookoutv2/gen/restapi/operations/get_job_run_error_responses.go
+++ b/internal/lookout/gen/restapi/operations/get_job_run_error_responses.go
@@ -10,7 +10,7 @@ import (
"github.com/go-openapi/runtime"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GetJobRunErrorOKCode is the HTTP code returned for type GetJobRunErrorOK
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_run_error_urlbuilder.go b/internal/lookout/gen/restapi/operations/get_job_run_error_urlbuilder.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_run_error_urlbuilder.go
rename to internal/lookout/gen/restapi/operations/get_job_run_error_urlbuilder.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_spec.go b/internal/lookout/gen/restapi/operations/get_job_spec.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_spec.go
rename to internal/lookout/gen/restapi/operations/get_job_spec.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_spec_parameters.go b/internal/lookout/gen/restapi/operations/get_job_spec_parameters.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_spec_parameters.go
rename to internal/lookout/gen/restapi/operations/get_job_spec_parameters.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_spec_responses.go b/internal/lookout/gen/restapi/operations/get_job_spec_responses.go
similarity index 98%
rename from internal/lookoutv2/gen/restapi/operations/get_job_spec_responses.go
rename to internal/lookout/gen/restapi/operations/get_job_spec_responses.go
index 8c4776d0f47..1112604b3ac 100644
--- a/internal/lookoutv2/gen/restapi/operations/get_job_spec_responses.go
+++ b/internal/lookout/gen/restapi/operations/get_job_spec_responses.go
@@ -10,7 +10,7 @@ import (
"github.com/go-openapi/runtime"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GetJobSpecOKCode is the HTTP code returned for type GetJobSpecOK
diff --git a/internal/lookoutv2/gen/restapi/operations/get_job_spec_urlbuilder.go b/internal/lookout/gen/restapi/operations/get_job_spec_urlbuilder.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_job_spec_urlbuilder.go
rename to internal/lookout/gen/restapi/operations/get_job_spec_urlbuilder.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_jobs.go b/internal/lookout/gen/restapi/operations/get_jobs.go
similarity index 99%
rename from internal/lookoutv2/gen/restapi/operations/get_jobs.go
rename to internal/lookout/gen/restapi/operations/get_jobs.go
index 1cb9fc27916..977c63e2955 100644
--- a/internal/lookoutv2/gen/restapi/operations/get_jobs.go
+++ b/internal/lookout/gen/restapi/operations/get_jobs.go
@@ -16,7 +16,7 @@ import (
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GetJobsHandlerFunc turns a function with the right signature into a get jobs handler
diff --git a/internal/lookoutv2/gen/restapi/operations/get_jobs_parameters.go b/internal/lookout/gen/restapi/operations/get_jobs_parameters.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_jobs_parameters.go
rename to internal/lookout/gen/restapi/operations/get_jobs_parameters.go
diff --git a/internal/lookoutv2/gen/restapi/operations/get_jobs_responses.go b/internal/lookout/gen/restapi/operations/get_jobs_responses.go
similarity index 98%
rename from internal/lookoutv2/gen/restapi/operations/get_jobs_responses.go
rename to internal/lookout/gen/restapi/operations/get_jobs_responses.go
index 5af80b4f316..f4b825584f8 100644
--- a/internal/lookoutv2/gen/restapi/operations/get_jobs_responses.go
+++ b/internal/lookout/gen/restapi/operations/get_jobs_responses.go
@@ -10,7 +10,7 @@ import (
"github.com/go-openapi/runtime"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GetJobsOKCode is the HTTP code returned for type GetJobsOK
diff --git a/internal/lookoutv2/gen/restapi/operations/get_jobs_urlbuilder.go b/internal/lookout/gen/restapi/operations/get_jobs_urlbuilder.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/get_jobs_urlbuilder.go
rename to internal/lookout/gen/restapi/operations/get_jobs_urlbuilder.go
diff --git a/internal/lookoutv2/gen/restapi/operations/group_jobs.go b/internal/lookout/gen/restapi/operations/group_jobs.go
similarity index 99%
rename from internal/lookoutv2/gen/restapi/operations/group_jobs.go
rename to internal/lookout/gen/restapi/operations/group_jobs.go
index 1f1ff8cbc26..a7b750b627b 100644
--- a/internal/lookoutv2/gen/restapi/operations/group_jobs.go
+++ b/internal/lookout/gen/restapi/operations/group_jobs.go
@@ -16,7 +16,7 @@ import (
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GroupJobsHandlerFunc turns a function with the right signature into a group jobs handler
diff --git a/internal/lookoutv2/gen/restapi/operations/group_jobs_parameters.go b/internal/lookout/gen/restapi/operations/group_jobs_parameters.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/group_jobs_parameters.go
rename to internal/lookout/gen/restapi/operations/group_jobs_parameters.go
diff --git a/internal/lookoutv2/gen/restapi/operations/group_jobs_responses.go b/internal/lookout/gen/restapi/operations/group_jobs_responses.go
similarity index 98%
rename from internal/lookoutv2/gen/restapi/operations/group_jobs_responses.go
rename to internal/lookout/gen/restapi/operations/group_jobs_responses.go
index b34b787fbbf..29ee3333db7 100644
--- a/internal/lookoutv2/gen/restapi/operations/group_jobs_responses.go
+++ b/internal/lookout/gen/restapi/operations/group_jobs_responses.go
@@ -10,7 +10,7 @@ import (
"github.com/go-openapi/runtime"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/models"
+ "github.com/armadaproject/armada/internal/lookout/gen/models"
)
// GroupJobsOKCode is the HTTP code returned for type GroupJobsOK
diff --git a/internal/lookoutv2/gen/restapi/operations/group_jobs_urlbuilder.go b/internal/lookout/gen/restapi/operations/group_jobs_urlbuilder.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/group_jobs_urlbuilder.go
rename to internal/lookout/gen/restapi/operations/group_jobs_urlbuilder.go
diff --git a/internal/lookoutv2/gen/restapi/operations/lookout_api.go b/internal/lookout/gen/restapi/operations/lookout_api.go
similarity index 100%
rename from internal/lookoutv2/gen/restapi/operations/lookout_api.go
rename to internal/lookout/gen/restapi/operations/lookout_api.go
diff --git a/internal/lookoutv2/gen/restapi/server.go b/internal/lookout/gen/restapi/server.go
similarity index 99%
rename from internal/lookoutv2/gen/restapi/server.go
rename to internal/lookout/gen/restapi/server.go
index 97cf93cee70..d5c7859e7d7 100644
--- a/internal/lookoutv2/gen/restapi/server.go
+++ b/internal/lookout/gen/restapi/server.go
@@ -24,7 +24,7 @@ import (
flags "github.com/jessevdk/go-flags"
"golang.org/x/net/netutil"
- "github.com/armadaproject/armada/internal/lookoutv2/gen/restapi/operations"
+ "github.com/armadaproject/armada/internal/lookout/gen/restapi/operations"
)
const (
diff --git a/internal/lookoutv2/generate/main.go b/internal/lookout/generate/main.go
similarity index 100%
rename from internal/lookoutv2/generate/main.go
rename to internal/lookout/generate/main.go
diff --git a/internal/lookoutv2/metrics/metrics.go b/internal/lookout/metrics/metrics.go
similarity index 100%
rename from internal/lookoutv2/metrics/metrics.go
rename to internal/lookout/metrics/metrics.go
diff --git a/internal/lookoutv2/model/model.go b/internal/lookout/model/model.go
similarity index 99%
rename from internal/lookoutv2/model/model.go
rename to internal/lookout/model/model.go
index 4a667167027..7ef6182414f 100644
--- a/internal/lookoutv2/model/model.go
+++ b/internal/lookout/model/model.go
@@ -40,6 +40,7 @@ type Job struct {
State string
Submitted time.Time
CancelReason *string
+ CancelUser *string
Node *string
Cluster string
ExitCode *int32
diff --git a/internal/lookoutv2/pruner/pruner.go b/internal/lookout/pruner/pruner.go
similarity index 100%
rename from internal/lookoutv2/pruner/pruner.go
rename to internal/lookout/pruner/pruner.go
diff --git a/internal/lookoutv2/pruner/pruner_test.go b/internal/lookout/pruner/pruner_test.go
similarity index 95%
rename from internal/lookoutv2/pruner/pruner_test.go
rename to internal/lookout/pruner/pruner_test.go
index cbe55f2040d..15a8e60ceb1 100644
--- a/internal/lookoutv2/pruner/pruner_test.go
+++ b/internal/lookout/pruner/pruner_test.go
@@ -15,10 +15,10 @@ import (
"github.com/armadaproject/armada/internal/common/database/lookout"
"github.com/armadaproject/armada/internal/common/slices"
"github.com/armadaproject/armada/internal/common/util"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutv2/repository"
+ "github.com/armadaproject/armada/internal/lookout/repository"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
)
var baseTime, _ = time.Parse("2006-01-02T15:04:05.000Z", "2022-03-01T15:04:05.000Z")
@@ -194,7 +194,7 @@ func storeJob(job testJob, db *lookoutdb.LookoutDb, converter *instructions.Inst
Build()
case lookout.JobCancelled:
simulator.
- Cancelled(job.ts).
+ Cancelled(job.ts, "canceluser").
Build()
case lookout.JobPreempted:
simulator.
diff --git a/internal/lookoutv2/repository/aggregates.go b/internal/lookout/repository/aggregates.go
similarity index 98%
rename from internal/lookoutv2/repository/aggregates.go
rename to internal/lookout/repository/aggregates.go
index e31ac234c7b..18840498f58 100644
--- a/internal/lookoutv2/repository/aggregates.go
+++ b/internal/lookout/repository/aggregates.go
@@ -8,7 +8,7 @@ import (
"github.com/armadaproject/armada/internal/common/database/lookout"
"github.com/armadaproject/armada/internal/common/slices"
"github.com/armadaproject/armada/internal/common/util"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
type QueryAggregator interface {
diff --git a/internal/lookoutv2/repository/fieldparser.go b/internal/lookout/repository/fieldparser.go
similarity index 97%
rename from internal/lookoutv2/repository/fieldparser.go
rename to internal/lookout/repository/fieldparser.go
index 5a61260aed9..0144692af5a 100644
--- a/internal/lookoutv2/repository/fieldparser.go
+++ b/internal/lookout/repository/fieldparser.go
@@ -9,7 +9,7 @@ import (
"github.com/pkg/errors"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
type FieldParser interface {
diff --git a/internal/lookoutv2/repository/getjoberror.go b/internal/lookout/repository/getjoberror.go
similarity index 100%
rename from internal/lookoutv2/repository/getjoberror.go
rename to internal/lookout/repository/getjoberror.go
diff --git a/internal/lookoutv2/repository/getjoberror_test.go b/internal/lookout/repository/getjoberror_test.go
similarity index 87%
rename from internal/lookoutv2/repository/getjoberror_test.go
rename to internal/lookout/repository/getjoberror_test.go
index 62599071bd8..cfc557e252d 100644
--- a/internal/lookoutv2/repository/getjoberror_test.go
+++ b/internal/lookout/repository/getjoberror_test.go
@@ -9,9 +9,9 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/compress"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
)
func TestGetJobError(t *testing.T) {
diff --git a/internal/lookoutv2/repository/getjobrundebugmessage.go b/internal/lookout/repository/getjobrundebugmessage.go
similarity index 100%
rename from internal/lookoutv2/repository/getjobrundebugmessage.go
rename to internal/lookout/repository/getjobrundebugmessage.go
diff --git a/internal/lookoutv2/repository/getjobrundebugmessage_test.go b/internal/lookout/repository/getjobrundebugmessage_test.go
similarity index 88%
rename from internal/lookoutv2/repository/getjobrundebugmessage_test.go
rename to internal/lookout/repository/getjobrundebugmessage_test.go
index fb18af46b09..1623c3474ec 100644
--- a/internal/lookoutv2/repository/getjobrundebugmessage_test.go
+++ b/internal/lookout/repository/getjobrundebugmessage_test.go
@@ -9,9 +9,9 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/compress"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
)
func TestGetJobRunDebugMessage(t *testing.T) {
diff --git a/internal/lookoutv2/repository/getjobrunerror.go b/internal/lookout/repository/getjobrunerror.go
similarity index 100%
rename from internal/lookoutv2/repository/getjobrunerror.go
rename to internal/lookout/repository/getjobrunerror.go
diff --git a/internal/lookoutv2/repository/getjobrunerror_test.go b/internal/lookout/repository/getjobrunerror_test.go
similarity index 88%
rename from internal/lookoutv2/repository/getjobrunerror_test.go
rename to internal/lookout/repository/getjobrunerror_test.go
index 31320616bcd..87c60837483 100644
--- a/internal/lookoutv2/repository/getjobrunerror_test.go
+++ b/internal/lookout/repository/getjobrunerror_test.go
@@ -9,9 +9,9 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/compress"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
)
func TestGetJobRunError(t *testing.T) {
diff --git a/internal/lookoutv2/repository/getjobs.go b/internal/lookout/repository/getjobs.go
similarity index 96%
rename from internal/lookoutv2/repository/getjobs.go
rename to internal/lookout/repository/getjobs.go
index 14ea7596c91..9281ef6873f 100644
--- a/internal/lookoutv2/repository/getjobs.go
+++ b/internal/lookout/repository/getjobs.go
@@ -11,7 +11,7 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/database"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
type GetJobsRepository interface {
@@ -47,6 +47,7 @@ type jobRow struct {
priorityClass sql.NullString
latestRunId sql.NullString
cancelReason sql.NullString
+ cancelUser sql.NullString
}
func NewSqlGetJobsRepository(db *pgxpool.Pool) *SqlGetJobsRepository {
@@ -102,6 +103,7 @@ func (r *SqlGetJobsRepository) getJobs(ctx *armadacontext.Context, filters []*mo
&row.priorityClass,
&row.latestRunId,
&row.cancelReason,
+ &row.cancelUser,
&annotations,
&runs,
); err != nil {
@@ -170,5 +172,6 @@ func jobRowToModel(row *jobRow) *model.Job {
State: string(lookout.JobStateMap[row.state]),
Submitted: row.submitted,
CancelReason: database.ParseNullString(row.cancelReason),
+ CancelUser: database.ParseNullString(row.cancelUser),
}
}
diff --git a/internal/lookoutv2/repository/getjobs_test.go b/internal/lookout/repository/getjobs_test.go
similarity index 98%
rename from internal/lookoutv2/repository/getjobs_test.go
rename to internal/lookout/repository/getjobs_test.go
index 2e177a20106..c7ec4fc0049 100644
--- a/internal/lookoutv2/repository/getjobs_test.go
+++ b/internal/lookout/repository/getjobs_test.go
@@ -17,20 +17,21 @@ import (
"github.com/armadaproject/armada/internal/common/compress"
"github.com/armadaproject/armada/internal/common/database/lookout"
"github.com/armadaproject/armada/internal/common/util"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
)
const (
- jobId = "01f3j0g1md4qx7z5qb148qnh4d"
- queue = "queue-1"
- jobSet = "job-set-1"
- cluster = "cluster-1"
- owner = "user-1"
- namespace = "namespace-1"
- priority = 12
+ jobId = "01f3j0g1md4qx7z5qb148qnh4d"
+ queue = "queue-1"
+ jobSet = "job-set-1"
+ cluster = "cluster-1"
+ owner = "user-1"
+ cancelUser = "canceluser"
+ namespace = "namespace-1"
+ priority = 12
userAnnotationPrefix = "armadaproject.io/"
)
@@ -1978,13 +1979,13 @@ func TestGetJobsActiveJobSet(t *testing.T) {
inactiveJobSet1 := NewJobSimulatorWithClock(converter, store, testClock).
Submit("queue-1", "job-set-1", owner, namespace, baseTime, &JobOptions{}).
- Cancelled(baseTime.Add(1 * time.Minute)).
+ Cancelled(baseTime.Add(1*time.Minute), cancelUser).
Build().
Job()
NewJobSimulatorWithClock(converter, store, testClock).
Submit("queue-2", "job-set-2", owner, namespace, baseTime, &JobOptions{}).
- Cancelled(baseTime.Add(1 * time.Minute)).
+ Cancelled(baseTime.Add(1*time.Minute), cancelUser).
Build().
Job()
diff --git a/internal/lookoutv2/repository/getjobspec.go b/internal/lookout/repository/getjobspec.go
similarity index 100%
rename from internal/lookoutv2/repository/getjobspec.go
rename to internal/lookout/repository/getjobspec.go
diff --git a/internal/lookoutv2/repository/getjobspec_test.go b/internal/lookout/repository/getjobspec_test.go
similarity index 96%
rename from internal/lookoutv2/repository/getjobspec_test.go
rename to internal/lookout/repository/getjobspec_test.go
index 7eeb439905b..8314f987e0b 100644
--- a/internal/lookoutv2/repository/getjobspec_test.go
+++ b/internal/lookout/repository/getjobspec_test.go
@@ -10,9 +10,9 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/compress"
"github.com/armadaproject/armada/internal/common/database/lookout"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
"github.com/armadaproject/armada/pkg/api"
)
diff --git a/internal/lookoutv2/repository/groupjobs.go b/internal/lookout/repository/groupjobs.go
similarity index 98%
rename from internal/lookoutv2/repository/groupjobs.go
rename to internal/lookout/repository/groupjobs.go
index 31d2b2de12c..dfd8894dfd5 100644
--- a/internal/lookoutv2/repository/groupjobs.go
+++ b/internal/lookout/repository/groupjobs.go
@@ -11,7 +11,7 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/slices"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
type GroupByResult struct {
diff --git a/internal/lookoutv2/repository/groupjobs_test.go b/internal/lookout/repository/groupjobs_test.go
similarity index 99%
rename from internal/lookoutv2/repository/groupjobs_test.go
rename to internal/lookout/repository/groupjobs_test.go
index 392c9ea61f3..63ccfe90e14 100644
--- a/internal/lookoutv2/repository/groupjobs_test.go
+++ b/internal/lookout/repository/groupjobs_test.go
@@ -14,10 +14,10 @@ import (
"github.com/armadaproject/armada/internal/common/compress"
"github.com/armadaproject/armada/internal/common/database/lookout"
"github.com/armadaproject/armada/internal/common/pointer"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
)
func withGroupJobsSetup(f func(*instructions.InstructionConverter, *lookoutdb.LookoutDb, *SqlGroupJobsRepository) error) error {
@@ -1575,7 +1575,7 @@ func makeCancelled(opts *createJobsOpts, converter *instructions.InstructionConv
Submit(opts.queue, opts.jobSet, owner, namespace, tSubmit, &JobOptions{
Annotations: opts.annotations,
}).
- Cancelled(lastTransitionTime).
+ Cancelled(lastTransitionTime, cancelUser).
Build()
}
diff --git a/internal/lookoutv2/repository/querybuilder.go b/internal/lookout/repository/querybuilder.go
similarity index 99%
rename from internal/lookoutv2/repository/querybuilder.go
rename to internal/lookout/repository/querybuilder.go
index 51702f1c70f..39798b26ae2 100644
--- a/internal/lookoutv2/repository/querybuilder.go
+++ b/internal/lookout/repository/querybuilder.go
@@ -9,7 +9,7 @@ import (
"github.com/armadaproject/armada/internal/common/database/lookout"
log "github.com/armadaproject/armada/internal/common/logging"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
const (
@@ -108,6 +108,7 @@ func (qb *QueryBuilder) GetJobs(
selected_jobs.priority_class,
selected_jobs.latest_run_id,
selected_jobs.cancel_reason,
+ selected_jobs.cancel_user,
selected_jobs.annotations,
selected_runs.runs
FROM (
diff --git a/internal/lookoutv2/repository/tables.go b/internal/lookout/repository/tables.go
similarity index 98%
rename from internal/lookoutv2/repository/tables.go
rename to internal/lookout/repository/tables.go
index 3e287316f2e..de9eeedfcd1 100644
--- a/internal/lookoutv2/repository/tables.go
+++ b/internal/lookout/repository/tables.go
@@ -4,7 +4,7 @@ import (
"github.com/pkg/errors"
"github.com/armadaproject/armada/internal/common/util"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
)
const (
diff --git a/internal/lookoutv2/repository/util.go b/internal/lookout/repository/util.go
similarity index 91%
rename from internal/lookoutv2/repository/util.go
rename to internal/lookout/repository/util.go
index 6c136532626..56531e62b80 100644
--- a/internal/lookoutv2/repository/util.go
+++ b/internal/lookout/repository/util.go
@@ -21,9 +21,9 @@ import (
protoutil "github.com/armadaproject/armada/internal/common/proto"
"github.com/armadaproject/armada/internal/common/pulsarutils"
"github.com/armadaproject/armada/internal/common/util"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutv2/model"
+ "github.com/armadaproject/armada/internal/lookout/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
"github.com/armadaproject/armada/pkg/api"
"github.com/armadaproject/armada/pkg/armadaevents"
)
@@ -82,6 +82,14 @@ func NewJobSimulatorWithClock(converter *instructions.InstructionConverter, stor
}
}
+func (js *JobSimulator) ForJobID(jobID string) *JobSimulator {
+ js.jobId = jobID
+ js.job = &model.Job{
+ JobId: jobID,
+ }
+ return js
+}
+
func (js *JobSimulator) Submit(queue, jobSet, owner, namespace string, timestamp time.Time, opts *JobOptions) *JobSimulator {
js.queue = queue
js.jobSet = jobSet
@@ -364,14 +372,15 @@ func (js *JobSimulator) LeaseReturned(runId string, message string, timestamp ti
return js
}
-func (js *JobSimulator) Cancelled(timestamp time.Time) *JobSimulator {
+func (js *JobSimulator) Cancelled(timestamp time.Time, cancelUser string) *JobSimulator {
ts := timestampOrNow(timestamp)
cancelledTime := protoutil.ToStdTime(ts)
cancelled := &armadaevents.EventSequence_Event{
Created: ts,
Event: &armadaevents.EventSequence_Event_CancelledJob{
CancelledJob: &armadaevents.CancelledJob{
- JobId: js.jobId,
+ JobId: js.jobId,
+ CancelUser: cancelUser,
},
},
}
@@ -379,6 +388,7 @@ func (js *JobSimulator) Cancelled(timestamp time.Time) *JobSimulator {
js.job.State = string(lookout.JobCancelled)
js.job.Cancelled = &cancelledTime
+ js.job.CancelUser = &cancelUser
js.job.LastTransitionTime = cancelledTime
return js
}
@@ -609,16 +619,53 @@ func (js *JobSimulator) LeaseExpired(runId string, timestamp time.Time, _ clock.
}
func (js *JobSimulator) Build() *JobSimulator {
- eventSequence := &armadaevents.EventSequence{
- Queue: js.queue,
- JobSetName: js.jobSet,
- UserId: js.owner,
- Events: js.events,
+ // Cancelled job events must be part of a different event sequence, as they can be initiated by a user which is not the owner of the job
+ eventSequences := []*armadaevents.EventSequence{}
+ eventsInCurrentSequence := make([]*armadaevents.EventSequence_Event, 0, len(js.events))
+ for i, event := range js.events {
+ switch event.GetEvent().(type) {
+ case *armadaevents.EventSequence_Event_CancelledJob:
+ eventSequences = append(
+ eventSequences,
+ &armadaevents.EventSequence{
+ Queue: js.queue,
+ JobSetName: js.jobSet,
+ UserId: js.owner,
+ Events: eventsInCurrentSequence,
+ },
+ &armadaevents.EventSequence{
+ Queue: js.queue,
+ JobSetName: js.jobSet,
+ UserId: *js.job.CancelUser,
+ Events: []*armadaevents.EventSequence_Event{event},
+ },
+ )
+ eventsInCurrentSequence = make([]*armadaevents.EventSequence_Event, 0, len(js.events)-i)
+ default:
+ eventsInCurrentSequence = append(eventsInCurrentSequence, event)
+ }
+ }
+ if len(eventsInCurrentSequence) > 0 {
+ eventSequences = append(
+ eventSequences,
+ &armadaevents.EventSequence{
+ Queue: js.queue,
+ JobSetName: js.jobSet,
+ UserId: js.owner,
+ Events: eventsInCurrentSequence,
+ },
+ )
+ }
+
+ messageIds := make([]pulsar.MessageID, len(eventSequences))
+ for i := 0; i < len(eventSequences); i++ {
+ messageIds[i] = pulsarutils.NewMessageId(i + 1)
}
eventSequenceWithIds := &utils.EventsWithIds[*armadaevents.EventSequence]{
- Events: []*armadaevents.EventSequence{eventSequence},
- MessageIds: []pulsar.MessageID{pulsarutils.NewMessageId(1)},
+ Events: eventSequences,
+ MessageIds: messageIds,
}
+
instructionSet := js.converter.Convert(armadacontext.TODO(), eventSequenceWithIds)
err := js.store.Store(armadacontext.TODO(), instructionSet)
if err != nil {
diff --git a/internal/lookoutv2/schema/migrations/001_initial_schema.sql b/internal/lookout/schema/migrations/001_initial_schema.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/001_initial_schema.sql
rename to internal/lookout/schema/migrations/001_initial_schema.sql
diff --git a/internal/lookoutv2/schema/migrations/002_cancel_reason.sql b/internal/lookout/schema/migrations/002_cancel_reason.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/002_cancel_reason.sql
rename to internal/lookout/schema/migrations/002_cancel_reason.sql
diff --git a/internal/lookoutv2/schema/migrations/003_run_leased_column.sql b/internal/lookout/schema/migrations/003_run_leased_column.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/003_run_leased_column.sql
rename to internal/lookout/schema/migrations/003_run_leased_column.sql
diff --git a/internal/lookoutv2/schema/migrations/004_job_namespace.sql b/internal/lookout/schema/migrations/004_job_namespace.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/004_job_namespace.sql
rename to internal/lookout/schema/migrations/004_job_namespace.sql
diff --git a/internal/lookoutv2/schema/migrations/005_annotations.sql b/internal/lookout/schema/migrations/005_annotations.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/005_annotations.sql
rename to internal/lookout/schema/migrations/005_annotations.sql
diff --git a/internal/lookoutv2/schema/migrations/006_annotations_constraint.sql b/internal/lookout/schema/migrations/006_annotations_constraint.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/006_annotations_constraint.sql
rename to internal/lookout/schema/migrations/006_annotations_constraint.sql
diff --git a/internal/lookoutv2/schema/migrations/007_queue.sql b/internal/lookout/schema/migrations/007_queue.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/007_queue.sql
rename to internal/lookout/schema/migrations/007_queue.sql
diff --git a/internal/lookoutv2/schema/migrations/008_run_debug_column.sql b/internal/lookout/schema/migrations/008_run_debug_column.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/008_run_debug_column.sql
rename to internal/lookout/schema/migrations/008_run_debug_column.sql
diff --git a/internal/lookoutv2/schema/migrations/009_job_deduplication.sql b/internal/lookout/schema/migrations/009_job_deduplication.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/009_job_deduplication.sql
rename to internal/lookout/schema/migrations/009_job_deduplication.sql
diff --git a/internal/lookoutv2/schema/migrations/010_drop_unused_table_and_indexes.sql b/internal/lookout/schema/migrations/010_drop_unused_table_and_indexes.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/010_drop_unused_table_and_indexes.sql
rename to internal/lookout/schema/migrations/010_drop_unused_table_and_indexes.sql
diff --git a/internal/lookoutv2/schema/migrations/011_add_job_error.sql b/internal/lookout/schema/migrations/011_add_job_error.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/011_add_job_error.sql
rename to internal/lookout/schema/migrations/011_add_job_error.sql
diff --git a/internal/lookoutv2/schema/migrations/012_add_job_submitted_index.sql b/internal/lookout/schema/migrations/012_add_job_submitted_index.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/012_add_job_submitted_index.sql
rename to internal/lookout/schema/migrations/012_add_job_submitted_index.sql
diff --git a/internal/lookoutv2/schema/migrations/013_add_job_spec_table.sql b/internal/lookout/schema/migrations/013_add_job_spec_table.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/013_add_job_spec_table.sql
rename to internal/lookout/schema/migrations/013_add_job_spec_table.sql
diff --git a/internal/lookoutv2/schema/migrations/014_add_external_job_uri.sql b/internal/lookout/schema/migrations/014_add_external_job_uri.sql
similarity index 100%
rename from internal/lookoutv2/schema/migrations/014_add_external_job_uri.sql
rename to internal/lookout/schema/migrations/014_add_external_job_uri.sql
diff --git a/internal/lookout/schema/migrations/015_add_cancel_user.sql b/internal/lookout/schema/migrations/015_add_cancel_user.sql
new file mode 100644
index 00000000000..5b97c4d6059
--- /dev/null
+++ b/internal/lookout/schema/migrations/015_add_cancel_user.sql
@@ -0,0 +1 @@
+ALTER TABLE job ADD COLUMN cancel_user varchar(512) NULL;
\ No newline at end of file
diff --git a/internal/lookoutv2/schema/schema.go b/internal/lookout/schema/schema.go
similarity index 100%
rename from internal/lookoutv2/schema/schema.go
rename to internal/lookout/schema/schema.go
diff --git a/internal/lookoutv2/swagger.yaml b/internal/lookout/swagger.yaml
similarity index 99%
rename from internal/lookoutv2/swagger.yaml
rename to internal/lookout/swagger.yaml
index 7deed115530..12d30c1baf1 100644
--- a/internal/lookoutv2/swagger.yaml
+++ b/internal/lookout/swagger.yaml
@@ -1,5 +1,5 @@
---
-swagger: '2.0'
+swagger: "2.0"
info:
version: 2.0.0
title: Lookout v2 API
@@ -116,6 +116,9 @@ definitions:
cancelReason:
type: string
x-nullable: true
+ cancelUser:
+ type: string
+ x-nullable: true
node:
type: string
x-nullable: true
diff --git a/internal/lookoutingesterv2/benchmark/benchmark.go b/internal/lookoutingester/benchmark/benchmark.go
similarity index 91%
rename from internal/lookoutingesterv2/benchmark/benchmark.go
rename to internal/lookoutingester/benchmark/benchmark.go
index 494bf7578bb..062639a0993 100644
--- a/internal/lookoutingesterv2/benchmark/benchmark.go
+++ b/internal/lookoutingester/benchmark/benchmark.go
@@ -14,14 +14,14 @@ import (
"github.com/armadaproject/armada/internal/common/armadacontext"
"github.com/armadaproject/armada/internal/common/database"
"github.com/armadaproject/armada/internal/common/util"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/configuration"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/model"
- "github.com/armadaproject/armada/internal/lookoutv2/schema"
+ "github.com/armadaproject/armada/internal/lookout/schema"
+ "github.com/armadaproject/armada/internal/lookoutingester/configuration"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/model"
)
-func withDbBenchmark(b *testing.B, config configuration.LookoutIngesterV2Configuration, action func(b *testing.B, db *pgxpool.Pool)) {
+func withDbBenchmark(b *testing.B, config configuration.LookoutIngesterConfiguration, action func(b *testing.B, db *pgxpool.Pool)) {
migrations, err := schema.LookoutMigrations()
if err != nil {
panic(err)
@@ -41,7 +41,7 @@ func withDbBenchmark(b *testing.B, config configuration.LookoutIngesterV2Configu
}
}
-func benchmarkSubmissions1000(b *testing.B, config configuration.LookoutIngesterV2Configuration) {
+func benchmarkSubmissions1000(b *testing.B, config configuration.LookoutIngesterConfiguration) {
const n = 1000
jobIds := makeUlids(n)
jobsToCreate := createJobInstructions(jobIds, n)
@@ -59,7 +59,7 @@ func benchmarkSubmissions1000(b *testing.B, config configuration.LookoutIngester
})
}
-func benchmarkSubmissions10000(b *testing.B, config configuration.LookoutIngesterV2Configuration) {
+func benchmarkSubmissions10000(b *testing.B, config configuration.LookoutIngesterConfiguration) {
const n = 10000
jobIds := makeUlids(n)
jobsToCreate := createJobInstructions(jobIds, n)
@@ -77,7 +77,7 @@ func benchmarkSubmissions10000(b *testing.B, config configuration.LookoutIngeste
})
}
-func benchmarkUpdates1000(b *testing.B, config configuration.LookoutIngesterV2Configuration) {
+func benchmarkUpdates1000(b *testing.B, config configuration.LookoutIngesterConfiguration) {
const n = 1000
const updatesPerJob = 5
const runsPerJob = 3
@@ -113,7 +113,7 @@ func benchmarkUpdates1000(b *testing.B, config configuration.LookoutIngesterV2Co
})
}
-func benchmarkUpdates10000(b *testing.B, config configuration.LookoutIngesterV2Configuration) {
+func benchmarkUpdates10000(b *testing.B, config configuration.LookoutIngesterConfiguration) {
const n = 10000
const updatesPerJob = 5
const runsPerJob = 3
@@ -261,14 +261,14 @@ func printBenchmarkResults(result testing.BenchmarkResult) {
)
}
-func apply(f func(b *testing.B, config configuration.LookoutIngesterV2Configuration), config configuration.LookoutIngesterV2Configuration) func(b *testing.B) {
+func apply(f func(b *testing.B, config configuration.LookoutIngesterConfiguration), config configuration.LookoutIngesterConfiguration) func(b *testing.B) {
return func(b *testing.B) {
f(b, config)
}
}
-// RunBenchmark executes benchmarking functions defined above for LookoutIngesterV2 database saving logic
-func RunBenchmark(config configuration.LookoutIngesterV2Configuration) {
+// RunBenchmark executes benchmarking functions defined above for LookoutIngester database saving logic
+func RunBenchmark(config configuration.LookoutIngesterConfiguration) {
benchmarkFns := map[string]func(b *testing.B){
"benchmarkSubmissions1000": apply(benchmarkSubmissions1000, config),
"benchmarkSubmissions10000": apply(benchmarkSubmissions10000, config),
diff --git a/internal/lookoutingesterv2/configuration/types.go b/internal/lookoutingester/configuration/types.go
similarity index 97%
rename from internal/lookoutingesterv2/configuration/types.go
rename to internal/lookoutingester/configuration/types.go
index e2998c9e5be..2f10db34164 100644
--- a/internal/lookoutingesterv2/configuration/types.go
+++ b/internal/lookoutingester/configuration/types.go
@@ -8,7 +8,7 @@ import (
"github.com/armadaproject/armada/internal/server/configuration"
)
-type LookoutIngesterV2Configuration struct {
+type LookoutIngesterConfiguration struct {
// Database configuration
Postgres configuration.PostgresConfig
// Metrics configuration
diff --git a/internal/lookoutingesterv2/configuration/validation.go b/internal/lookoutingester/configuration/validation.go
similarity index 68%
rename from internal/lookoutingesterv2/configuration/validation.go
rename to internal/lookoutingester/configuration/validation.go
index c78f1df1d19..128bef0dee7 100644
--- a/internal/lookoutingesterv2/configuration/validation.go
+++ b/internal/lookoutingester/configuration/validation.go
@@ -2,7 +2,7 @@ package configuration
import "github.com/go-playground/validator/v10"
-func (c LookoutIngesterV2Configuration) Validate() error {
+func (c LookoutIngesterConfiguration) Validate() error {
validate := validator.New()
return validate.Struct(c)
}
diff --git a/internal/lookoutingesterv2/dbloadtester/queue.go b/internal/lookoutingester/dbloadtester/queue.go
similarity index 100%
rename from internal/lookoutingesterv2/dbloadtester/queue.go
rename to internal/lookoutingester/dbloadtester/queue.go
diff --git a/internal/lookoutingesterv2/dbloadtester/simulator.go b/internal/lookoutingester/dbloadtester/simulator.go
similarity index 93%
rename from internal/lookoutingesterv2/dbloadtester/simulator.go
rename to internal/lookoutingester/dbloadtester/simulator.go
index b298bf74827..5f069409d9c 100644
--- a/internal/lookoutingesterv2/dbloadtester/simulator.go
+++ b/internal/lookoutingester/dbloadtester/simulator.go
@@ -16,11 +16,11 @@ import (
"github.com/armadaproject/armada/internal/common/ingest"
"github.com/armadaproject/armada/internal/common/ingest/utils"
log "github.com/armadaproject/armada/internal/common/logging"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/configuration"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/configuration"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/model"
"github.com/armadaproject/armada/pkg/armadaevents"
clientUtil "github.com/armadaproject/armada/pkg/client/util"
)
@@ -53,7 +53,7 @@ type Results struct {
TotalEventsProcessed int
}
-func Setup(lookoutIngesterConfig configuration.LookoutIngesterV2Configuration, testConfig Config) *LoadTester {
+func Setup(lookoutIngesterConfig configuration.LookoutIngesterConfiguration, testConfig Config) *LoadTester {
m := metrics.Get()
db, err := database.OpenPgxPool(lookoutIngesterConfig.Postgres)
diff --git a/internal/lookoutingesterv2/dbloadtester/test_data.yaml b/internal/lookoutingester/dbloadtester/test_data.yaml
similarity index 100%
rename from internal/lookoutingesterv2/dbloadtester/test_data.yaml
rename to internal/lookoutingester/dbloadtester/test_data.yaml
diff --git a/internal/lookoutingesterv2/ingester.go b/internal/lookoutingester/ingester.go
similarity index 85%
rename from internal/lookoutingesterv2/ingester.go
rename to internal/lookoutingester/ingester.go
index feadfce9939..4a9e7864fea 100644
--- a/internal/lookoutingesterv2/ingester.go
+++ b/internal/lookoutingester/ingester.go
@@ -1,4 +1,4 @@
-package lookoutingesterv2
+package lookoutingester
import (
"regexp"
@@ -15,17 +15,17 @@ import (
"github.com/armadaproject/armada/internal/common/ingest/jobsetevents"
log "github.com/armadaproject/armada/internal/common/logging"
"github.com/armadaproject/armada/internal/common/profiling"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/configuration"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/instructions"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/lookoutdb"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/configuration"
+ "github.com/armadaproject/armada/internal/lookoutingester/instructions"
+ "github.com/armadaproject/armada/internal/lookoutingester/lookoutdb"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/model"
"github.com/armadaproject/armada/pkg/armadaevents"
)
// Run will create a pipeline that will take Armada event messages from Pulsar and update the
// Lookout database accordingly. This pipeline will run until a SIGTERM is received
-func Run(config *configuration.LookoutIngesterV2Configuration) {
+func Run(config *configuration.LookoutIngesterConfiguration) {
log.Infof("Opening connection pool to postgres")
m := metrics.Get()
db, err := database.OpenPgxPool(config.Postgres)
diff --git a/internal/lookoutingesterv2/instructions/instructions.go b/internal/lookoutingester/instructions/instructions.go
similarity index 98%
rename from internal/lookoutingesterv2/instructions/instructions.go
rename to internal/lookoutingester/instructions/instructions.go
index 04e85cc13e6..e5940927d17 100644
--- a/internal/lookoutingesterv2/instructions/instructions.go
+++ b/internal/lookoutingester/instructions/instructions.go
@@ -17,7 +17,7 @@ import (
log "github.com/armadaproject/armada/internal/common/logging"
protoutil "github.com/armadaproject/armada/internal/common/proto"
"github.com/armadaproject/armada/internal/common/util"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/model"
"github.com/armadaproject/armada/pkg/api"
"github.com/armadaproject/armada/pkg/armadaevents"
)
@@ -70,7 +70,7 @@ func (c *InstructionConverter) Convert(ctx *armadacontext.Context, sequences *ut
}
func (c *InstructionConverter) convertSequence(
- ctx *armadacontext.Context,
+ _ *armadacontext.Context,
sequence *armadaevents.EventSequence,
update *model.InstructionSet,
) {
@@ -210,7 +210,7 @@ func extractUserAnnotations(userAnnotationPrefix string, jobAnnotations map[stri
return result
}
-func (c *InstructionConverter) handleReprioritiseJob(ts time.Time, event *armadaevents.ReprioritisedJob, update *model.InstructionSet) error {
+func (c *InstructionConverter) handleReprioritiseJob(_ time.Time, event *armadaevents.ReprioritisedJob, update *model.InstructionSet) error {
jobUpdate := model.UpdateJobInstruction{
JobId: event.JobId,
Priority: pointer.Int64(int64(event.Priority)),
@@ -224,11 +224,17 @@ func (c *InstructionConverter) handleCancelledJob(ts time.Time, event *armadaeve
if event.Reason != "" {
reason = &event.Reason
}
+
+ var cancelUser *string
+ if event.CancelUser != "" {
+ cancelUser = &event.CancelUser
+ }
jobUpdate := model.UpdateJobInstruction{
JobId: event.GetJobId(),
State: pointer.Int32(int32(lookout.JobCancelledOrdinal)),
Cancelled: &ts,
CancelReason: reason,
+ CancelUser: cancelUser,
LastTransitionTime: &ts,
LastTransitionTimeSeconds: pointer.Int64(ts.Unix()),
}
diff --git a/internal/lookoutingesterv2/instructions/instructions_test.go b/internal/lookoutingester/instructions/instructions_test.go
similarity index 98%
rename from internal/lookoutingesterv2/instructions/instructions_test.go
rename to internal/lookoutingester/instructions/instructions_test.go
index 19dee86f1b9..d59b5700cb1 100644
--- a/internal/lookoutingesterv2/instructions/instructions_test.go
+++ b/internal/lookoutingester/instructions/instructions_test.go
@@ -20,8 +20,8 @@ import (
"github.com/armadaproject/armada/internal/common/ingest/utils"
protoutil "github.com/armadaproject/armada/internal/common/proto"
"github.com/armadaproject/armada/internal/common/pulsarutils"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/model"
"github.com/armadaproject/armada/pkg/api"
"github.com/armadaproject/armada/pkg/armadaevents"
)
@@ -106,6 +106,7 @@ var expectedJobCancelled = model.UpdateJobInstruction{
JobId: testfixtures.JobId,
State: pointer.Int32(lookout.JobCancelledOrdinal),
Cancelled: &testfixtures.BaseTime,
+ CancelUser: pointer.String(testfixtures.CancelUser),
LastTransitionTime: &testfixtures.BaseTime,
LastTransitionTimeSeconds: pointer.Int64(testfixtures.BaseTime.Unix()),
}
@@ -319,6 +320,7 @@ func TestConvert(t *testing.T) {
JobId: testfixtures.JobId,
State: pointer.Int32(lookout.JobCancelledOrdinal),
CancelReason: pointer.String("some reason"),
+ CancelUser: pointer.String(testfixtures.CancelUser),
Cancelled: &testfixtures.BaseTime,
LastTransitionTime: &testfixtures.BaseTime,
LastTransitionTimeSeconds: pointer.Int64(testfixtures.BaseTime.Unix()),
diff --git a/internal/lookoutingesterv2/lookoutdb/insertion.go b/internal/lookoutingester/lookoutdb/insertion.go
similarity index 98%
rename from internal/lookoutingesterv2/lookoutdb/insertion.go
rename to internal/lookoutingester/lookoutdb/insertion.go
index 6b68c40d27c..88d1b829976 100644
--- a/internal/lookoutingesterv2/lookoutdb/insertion.go
+++ b/internal/lookoutingester/lookoutdb/insertion.go
@@ -14,8 +14,8 @@ import (
"github.com/armadaproject/armada/internal/common/database/lookout"
commonmetrics "github.com/armadaproject/armada/internal/common/ingest/metrics"
log "github.com/armadaproject/armada/internal/common/logging"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/model"
)
type LookoutDb struct {
@@ -374,7 +374,8 @@ func (l *LookoutDb) UpdateJobsBatch(ctx *armadacontext.Context, instructions []*
last_transition_time_seconds bigint,
duplicate bool,
latest_run_id varchar(36),
- cancel_reason varchar(512)
+ cancel_reason varchar(512),
+ cancel_user varchar(512)
) ON COMMIT DROP;`, tmpTable))
if err != nil {
l.metrics.RecordDBError(commonmetrics.DBOperationCreateTempTable)
@@ -395,6 +396,7 @@ func (l *LookoutDb) UpdateJobsBatch(ctx *armadacontext.Context, instructions []*
"duplicate",
"latest_run_id",
"cancel_reason",
+ "cancel_user",
},
pgx.CopyFromSlice(len(instructions), func(i int) ([]interface{}, error) {
return []interface{}{
@@ -407,6 +409,7 @@ func (l *LookoutDb) UpdateJobsBatch(ctx *armadacontext.Context, instructions []*
instructions[i].Duplicate,
instructions[i].LatestRunId,
instructions[i].CancelReason,
+ instructions[i].CancelUser,
}, nil
}),
)
@@ -425,7 +428,8 @@ func (l *LookoutDb) UpdateJobsBatch(ctx *armadacontext.Context, instructions []*
last_transition_time_seconds = coalesce(tmp.last_transition_time_seconds, job.last_transition_time_seconds),
duplicate = coalesce(tmp.duplicate, job.duplicate),
latest_run_id = coalesce(tmp.latest_run_id, job.latest_run_id),
- cancel_reason = coalesce(tmp.cancel_reason, job.cancel_reason)
+ cancel_reason = coalesce(tmp.cancel_reason, job.cancel_reason),
+ cancel_user = coalesce(tmp.cancel_user, job.cancel_user)
FROM %s as tmp WHERE tmp.job_id = job.job_id`, tmpTable),
)
if err != nil {
@@ -448,7 +452,8 @@ func (l *LookoutDb) UpdateJobsScalar(ctx *armadacontext.Context, instructions []
last_transition_time_seconds = coalesce($6, job.last_transition_time_seconds),
duplicate = coalesce($7, duplicate),
latest_run_id = coalesce($8, job.latest_run_id),
- cancel_reason = coalesce($9, job.cancel_reason)
+ cancel_reason = coalesce($9, job.cancel_reason),
+ cancel_user = coalesce($10, job.cancel_user)
WHERE job_id = $1`
for _, i := range instructions {
err := l.withDatabaseRetryInsert(func() error {
@@ -461,7 +466,8 @@ func (l *LookoutDb) UpdateJobsScalar(ctx *armadacontext.Context, instructions []
i.LastTransitionTimeSeconds,
i.Duplicate,
i.LatestRunId,
- i.CancelReason)
+ i.CancelReason,
+ i.CancelUser)
if err != nil {
l.metrics.RecordDBError(commonmetrics.DBOperationUpdate)
}
diff --git a/internal/lookoutingesterv2/lookoutdb/insertion_test.go b/internal/lookoutingester/lookoutdb/insertion_test.go
similarity index 99%
rename from internal/lookoutingesterv2/lookoutdb/insertion_test.go
rename to internal/lookoutingester/lookoutdb/insertion_test.go
index ee8c4c14aba..fb6324075f1 100644
--- a/internal/lookoutingesterv2/lookoutdb/insertion_test.go
+++ b/internal/lookoutingester/lookoutdb/insertion_test.go
@@ -16,8 +16,8 @@ import (
"github.com/armadaproject/armada/internal/common/database/lookout"
"github.com/armadaproject/armada/internal/common/ingest/testfixtures"
"github.com/armadaproject/armada/internal/common/pulsarutils"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/metrics"
- "github.com/armadaproject/armada/internal/lookoutingesterv2/model"
+ "github.com/armadaproject/armada/internal/lookoutingester/metrics"
+ "github.com/armadaproject/armada/internal/lookoutingester/model"
)
const (
@@ -76,6 +76,7 @@ type JobRow struct {
PriorityClass string
LatestRunId *string
CancelReason *string
+ CancelUser *string
Annotations map[string]string
ExternalJobUri string
}
@@ -369,6 +370,7 @@ func TestUpdateJobsWithTerminal(t *testing.T) {
State: pointer.Int32(lookout.JobCancelledOrdinal),
Cancelled: &baseTime,
CancelReason: pointer.String("some reason"),
+ CancelUser: pointer.String(userId),
LastTransitionTime: &baseTime,
LastTransitionTimeSeconds: pointer.Int64(baseTime.Unix()),
},
@@ -423,6 +425,7 @@ func TestUpdateJobsWithTerminal(t *testing.T) {
job := getJob(t, db, JobId)
assert.Equal(t, lookout.JobCancelledOrdinal, int(job.State))
assert.Equal(t, "some reason", *job.CancelReason)
+ assert.Equal(t, testfixtures.UserId, *job.CancelUser)
job2 := getJob(t, db, "job2")
assert.Equal(t, lookout.JobSucceededOrdinal, int(job2.State))
@@ -968,6 +971,7 @@ func getJob(t *testing.T, db *pgxpool.Pool, jobId string) JobRow {
priority_class,
latest_run_id,
cancel_reason,
+ cancel_user,
annotations,
external_job_uri
FROM job WHERE job_id = $1`,
@@ -992,6 +996,7 @@ func getJob(t *testing.T, db *pgxpool.Pool, jobId string) JobRow {
&job.PriorityClass,
&job.LatestRunId,
&job.CancelReason,
+ &job.CancelUser,
&job.Annotations,
&job.ExternalJobUri,
)
diff --git a/internal/lookoutingesterv2/metrics/metrics.go b/internal/lookoutingester/metrics/metrics.go
similarity index 84%
rename from internal/lookoutingesterv2/metrics/metrics.go
rename to internal/lookoutingester/metrics/metrics.go
index 644ed10bf59..774c0c0dd07 100644
--- a/internal/lookoutingesterv2/metrics/metrics.go
+++ b/internal/lookoutingester/metrics/metrics.go
@@ -12,7 +12,7 @@ import (
// Lookout ingester specific metrics
var avRowChangeTimeHist = promauto.NewHistogram(
prometheus.HistogramOpts{
- Name: metrics.ArmadaLookoutIngesterV2MetricsPrefix + "average_row_change_time",
+ Name: metrics.ArmadaLookoutIngesterMetricsPrefix + "average_row_change_time",
Help: "Average time take in milliseconds to change one database row",
Buckets: []float64{0.1, 0.2, 0.5, 1, 2, 3, 5, 7, 10, 15, 25, 50, 100, 1000},
},
@@ -20,7 +20,7 @@ var avRowChangeTimeHist = promauto.NewHistogram(
var avRowChangeTimeByOperationHist = promauto.NewHistogramVec(
prometheus.HistogramOpts{
- Name: metrics.ArmadaLookoutIngesterV2MetricsPrefix + "average_row_change_time_by_operation",
+ Name: metrics.ArmadaLookoutIngesterMetricsPrefix + "average_row_change_time_by_operation",
Help: "Average time take in milliseconds to change one database row",
Buckets: []float64{0.1, 0.2, 0.5, 1, 2, 3, 5, 7, 10, 15, 25, 50, 100, 1000},
},
@@ -29,7 +29,7 @@ var avRowChangeTimeByOperationHist = promauto.NewHistogramVec(
var rowsChangedCounter = promauto.NewCounterVec(
prometheus.CounterOpts{
- Name: metrics.ArmadaLookoutIngesterV2MetricsPrefix + "rows_changed",
+ Name: metrics.ArmadaLookoutIngesterMetricsPrefix + "rows_changed",
Help: "Number of rows changed in the database",
},
[]string{"table", "operation"},
@@ -40,7 +40,7 @@ type Metrics struct {
}
var m = &Metrics{
- metrics.NewMetrics(metrics.ArmadaLookoutIngesterV2MetricsPrefix),
+ metrics.NewMetrics(metrics.ArmadaLookoutIngesterMetricsPrefix),
}
func Get() *Metrics {
diff --git a/internal/lookoutingesterv2/model/model.go b/internal/lookoutingester/model/model.go
similarity index 98%
rename from internal/lookoutingesterv2/model/model.go
rename to internal/lookoutingester/model/model.go
index 5a8fe519749..ca249f1d5f9 100644
--- a/internal/lookoutingesterv2/model/model.go
+++ b/internal/lookoutingester/model/model.go
@@ -35,6 +35,7 @@ type UpdateJobInstruction struct {
State *int32
Cancelled *time.Time
CancelReason *string
+ CancelUser *string
LastTransitionTime *time.Time
LastTransitionTimeSeconds *int64
Duplicate *bool
diff --git a/internal/lookoutui/README.md b/internal/lookoutui/README.md
index 7e1582d2cd7..8d30f34d8f8 100644
--- a/internal/lookoutui/README.md
+++ b/internal/lookoutui/README.md
@@ -73,6 +73,14 @@ yarn test --run
If you are actively changing unit tests or code covered by unit tests, you may
find it useful to omit `--run` to continuously run affected tests.
+### Run typechecker
+
+Ensure that the types in TypeScript source and test files are correct.
+
+```bash
+yarn typecheck
+```
+
### Lint
Formatting and linting is done using [Prettier](https://prettier.io/) and
diff --git a/internal/lookoutui/package.json b/internal/lookoutui/package.json
index a6409a60db9..408bd4029cb 100644
--- a/internal/lookoutui/package.json
+++ b/internal/lookoutui/package.json
@@ -12,6 +12,7 @@
"build": "vite build",
"serve": "vite preview",
"test": "vitest",
+ "typecheck": "tsc --noEmit",
"openapi": "docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v \"${PWD}/../../:/project\" openapitools/openapi-generator-cli:v5.4.0 /project/internal/lookoutui/openapi.sh",
"openapi:win": "powershell -Command \"$uid = (New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).Identity.User.Value; $gid = (Get-WmiObject Win32_UserAccount | Where-Object { $_.SID -eq $uid }).SID.Value; docker run --rm -e USERID=$uid -e GROUPID=$gid -v \"%cd%/../../:/project\" openapitools/openapi-generator-cli:v5.4.0 /project/internal/lookoutui/openapi.sh\"",
"lint": "eslint 'src/**/*.{js,ts,tsx}' --max-warnings 0",
diff --git a/internal/lookoutui/src/components/CodeBlock.tsx b/internal/lookoutui/src/components/CodeBlock.tsx
index f6cfa73d651..7642e3fedbc 100644
--- a/internal/lookoutui/src/components/CodeBlock.tsx
+++ b/internal/lookoutui/src/components/CodeBlock.tsx
@@ -37,18 +37,20 @@ const CodeBlockContainer = styled("div")({
},
})
-const StyledPre = styled("pre")<{ wrap: boolean }>(({ theme, wrap }) => ({
- lineHeight: 1.2,
- fontSize: theme.typography.body2.fontSize,
- overflow: "auto",
- padding: 5,
- borderRadius: 5,
- minHeight: 50,
- display: "flex",
- alignItems: "center",
- margin: 0,
- textWrap: wrap ? "wrap" : undefined,
-}))
+const StyledPre = styled("pre", { shouldForwardProp: (prop) => prop !== "wrap" })<{ wrap: boolean }>(
+ ({ theme, wrap }) => ({
+ lineHeight: 1.2,
+ fontSize: theme.typography.body2.fontSize,
+ overflow: "auto",
+ padding: 5,
+ borderRadius: 5,
+ minHeight: 50,
+ display: "flex",
+ alignItems: "center",
+ margin: 0,
+ textWrap: wrap ? "wrap" : undefined,
+ }),
+)
const Code = styled("code")({
display: "table",
diff --git a/internal/lookoutui/src/components/lookout/CancelDialog.test.tsx b/internal/lookoutui/src/components/lookout/CancelDialog.test.tsx
index 9405293d35a..8e71450bd2e 100644
--- a/internal/lookoutui/src/components/lookout/CancelDialog.test.tsx
+++ b/internal/lookoutui/src/components/lookout/CancelDialog.test.tsx
@@ -3,7 +3,7 @@ import userEvent from "@testing-library/user-event"
import { SnackbarProvider } from "notistack"
import { CancelDialog } from "./CancelDialog"
-import { Job, JobFilter, JobState, Match } from "../../models/lookoutModels"
+import { Job, JobFiltersWithExcludes, JobState, Match } from "../../models/lookoutModels"
import { IGetJobsService } from "../../services/lookout/GetJobsService"
import { UpdateJobsResponse, UpdateJobsService } from "../../services/lookout/UpdateJobsService"
import FakeGetJobsService from "../../services/lookout/mocks/FakeGetJobsService"
@@ -14,7 +14,7 @@ describe("CancelDialog", () => {
const numJobs = 5
const numFinishedJobs = 0
let jobs: Job[],
- selectedItemFilters: JobFilter[][],
+ selectedItemFilters: JobFiltersWithExcludes[],
getJobsService: IGetJobsService,
updateJobsService: UpdateJobsService,
onClose: () => void
@@ -22,13 +22,16 @@ describe("CancelDialog", () => {
beforeEach(() => {
jobs = makeManyTestJobs(numJobs, numFinishedJobs)
selectedItemFilters = [
- [
- {
- field: "jobId",
- value: "job-id-0",
- match: Match.Exact,
- },
- ],
+ {
+ jobFilters: [
+ {
+ field: "jobId",
+ value: "job-id-0",
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
]
getJobsService = new FakeGetJobsService(jobs)
updateJobsService = {
@@ -75,13 +78,16 @@ describe("CancelDialog", () => {
it("paginates through many jobs correctly", async () => {
jobs = makeManyTestJobs(6000, 6000 - 1480)
selectedItemFilters = [
- [
- {
- field: "queue",
- value: "queue-0",
- match: Match.Exact,
- },
- ],
+ {
+ jobFilters: [
+ {
+ field: "queue",
+ value: "queue-0",
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
]
getJobsService = new FakeGetJobsService(jobs)
@@ -157,20 +163,26 @@ describe("CancelDialog", () => {
it("handles a partial success", async () => {
// Select 2 jobs
selectedItemFilters = [
- [
- {
- field: "jobId",
- value: jobs[0].jobId,
- match: Match.Exact,
- },
- ],
- [
- {
- field: "jobId",
- value: jobs[1].jobId,
- match: Match.Exact,
- },
- ],
+ {
+ jobFilters: [
+ {
+ field: "jobId",
+ value: jobs[0].jobId,
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
+ {
+ jobFilters: [
+ {
+ field: "jobId",
+ value: jobs[1].jobId,
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
]
// jobs[1] in the dataset is terminated, so lets just fix that for the test
diff --git a/internal/lookoutui/src/components/lookout/CancelDialog.tsx b/internal/lookoutui/src/components/lookout/CancelDialog.tsx
index 24ca09f08cc..883b540d861 100644
--- a/internal/lookoutui/src/components/lookout/CancelDialog.tsx
+++ b/internal/lookoutui/src/components/lookout/CancelDialog.tsx
@@ -9,7 +9,7 @@ import _ from "lodash"
import dialogStyles from "./DialogStyles.module.css"
import { JobStatusTable } from "./JobStatusTable"
import { useCustomSnackbar } from "../../hooks/useCustomSnackbar"
-import { isTerminatedJobState, Job, JobFilter, JobId } from "../../models/lookoutModels"
+import { isTerminatedJobState, Job, JobFiltersWithExcludes, JobId } from "../../models/lookoutModels"
import { useGetAccessToken } from "../../oidcAuth"
import { IGetJobsService } from "../../services/lookout/GetJobsService"
import { UpdateJobsService } from "../../services/lookout/UpdateJobsService"
@@ -19,7 +19,7 @@ import { formatJobState } from "../../utils/jobsTableFormatters"
interface CancelDialogProps {
onClose: () => void
- selectedItemFilters: JobFilter[][]
+ selectedItemFilters: JobFiltersWithExcludes[]
getJobsService: IGetJobsService
updateJobsService: UpdateJobsService
}
diff --git a/internal/lookoutui/src/components/lookout/JobsTableActionBar.tsx b/internal/lookoutui/src/components/lookout/JobsTableActionBar.tsx
index 49c2a860e30..e26bf88038a 100644
--- a/internal/lookoutui/src/components/lookout/JobsTableActionBar.tsx
+++ b/internal/lookoutui/src/components/lookout/JobsTableActionBar.tsx
@@ -11,7 +11,7 @@ import { ReprioritiseDialog } from "./ReprioritiseDialog"
import AutoRefreshToggle from "../AutoRefreshToggle"
import RefreshButton from "../RefreshButton"
import GroupBySelect from "./GroupBySelect"
-import { JobFilter } from "../../models/lookoutModels"
+import { JobFiltersWithExcludes } from "../../models/lookoutModels"
import { IGetJobsService } from "../../services/lookout/GetJobsService"
import { UpdateJobsService } from "../../services/lookout/UpdateJobsService"
import { ColumnId, JobTableColumn, PINNED_COLUMNS, toColId } from "../../utils/jobsTableColumns"
@@ -25,7 +25,7 @@ export interface JobsTableActionBarProps {
visibleColumns: ColumnId[]
columnOrder: ColumnId[]
setColumnOrder: (columnOrder: ColumnId[]) => void
- selectedItemFilters: JobFilter[][]
+ selectedItemFilters: JobFiltersWithExcludes[]
customViews: string[]
activeJobSets: boolean
onActiveJobSetsChanged: (newVal: boolean) => void
diff --git a/internal/lookoutui/src/components/lookout/ReprioritiseDialog.test.tsx b/internal/lookoutui/src/components/lookout/ReprioritiseDialog.test.tsx
index 400f3098403..77dc67b9734 100644
--- a/internal/lookoutui/src/components/lookout/ReprioritiseDialog.test.tsx
+++ b/internal/lookoutui/src/components/lookout/ReprioritiseDialog.test.tsx
@@ -3,7 +3,7 @@ import userEvent from "@testing-library/user-event"
import { SnackbarProvider } from "notistack"
import { ReprioritiseDialog } from "./ReprioritiseDialog"
-import { Job, JobFilter, JobState, Match } from "../../models/lookoutModels"
+import { Job, JobFiltersWithExcludes, JobState, Match } from "../../models/lookoutModels"
import { IGetJobsService } from "../../services/lookout/GetJobsService"
import { UpdateJobsResponse, UpdateJobsService } from "../../services/lookout/UpdateJobsService"
import FakeGetJobsService from "../../services/lookout/mocks/FakeGetJobsService"
@@ -13,7 +13,7 @@ describe("ReprioritiseDialog", () => {
const numJobs = 5
const numFinishedJobs = 0
let jobs: Job[],
- selectedItemFilters: JobFilter[][],
+ selectedItemFilters: JobFiltersWithExcludes[],
getJobsService: IGetJobsService,
updateJobsService: UpdateJobsService,
onClose: () => void
@@ -21,13 +21,16 @@ describe("ReprioritiseDialog", () => {
beforeEach(() => {
jobs = makeManyTestJobs(numJobs, numFinishedJobs)
selectedItemFilters = [
- [
- {
- field: "jobId",
- value: "job-id-0",
- match: Match.Exact,
- },
- ],
+ {
+ jobFilters: [
+ {
+ field: "jobId",
+ value: "job-id-0",
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
]
getJobsService = new FakeGetJobsService(jobs)
updateJobsService = {
@@ -74,13 +77,16 @@ describe("ReprioritiseDialog", () => {
it("paginates through many jobs correctly", async () => {
jobs = makeManyTestJobs(6000, 6000 - 1480)
selectedItemFilters = [
- [
- {
- field: "queue",
- value: "queue-0",
- match: Match.Exact,
- },
- ],
+ {
+ jobFilters: [
+ {
+ field: "queue",
+ value: "queue-0",
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
]
getJobsService = new FakeGetJobsService(jobs)
@@ -163,20 +169,26 @@ describe("ReprioritiseDialog", () => {
it("handles a partial success", async () => {
// Select 2 jobs
selectedItemFilters = [
- [
- {
- field: "jobId",
- value: jobs[0].jobId,
- match: Match.Exact,
- },
- ],
- [
- {
- field: "jobId",
- value: jobs[1].jobId,
- match: Match.Exact,
- },
- ],
+ {
+ jobFilters: [
+ {
+ field: "jobId",
+ value: jobs[0].jobId,
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
+ {
+ jobFilters: [
+ {
+ field: "jobId",
+ value: jobs[1].jobId,
+ match: Match.Exact,
+ },
+ ],
+ excludesJobFilters: [],
+ },
]
// jobs[1] in the dataset is terminated, so lets just fix that for the test
diff --git a/internal/lookoutui/src/components/lookout/ReprioritiseDialog.tsx b/internal/lookoutui/src/components/lookout/ReprioritiseDialog.tsx
index de4f2f2aacd..bb6976f9959 100644
--- a/internal/lookoutui/src/components/lookout/ReprioritiseDialog.tsx
+++ b/internal/lookoutui/src/components/lookout/ReprioritiseDialog.tsx
@@ -17,7 +17,7 @@ import _ from "lodash"
import dialogStyles from "./DialogStyles.module.css"
import { JobStatusTable } from "./JobStatusTable"
import { useCustomSnackbar } from "../../hooks/useCustomSnackbar"
-import { isTerminatedJobState, Job, JobFilter, JobId } from "../../models/lookoutModels"
+import { isTerminatedJobState, Job, JobFiltersWithExcludes, JobId } from "../../models/lookoutModels"
import { useGetAccessToken } from "../../oidcAuth"
import { IGetJobsService } from "../../services/lookout/GetJobsService"
import { UpdateJobsService } from "../../services/lookout/UpdateJobsService"
@@ -26,7 +26,7 @@ import { getUniqueJobsMatchingFilters } from "../../utils/jobsDialogUtils"
interface ReprioritiseDialogProps {
onClose: () => void
- selectedItemFilters: JobFilter[][]
+ selectedItemFilters: JobFiltersWithExcludes[]
getJobsService: IGetJobsService
updateJobsService: UpdateJobsService
}
diff --git a/internal/lookoutui/src/components/lookout/sidebar/SidebarTabJobDetails.tsx b/internal/lookoutui/src/components/lookout/sidebar/SidebarTabJobDetails.tsx
index 40c46668b95..0b054a9cabd 100644
--- a/internal/lookoutui/src/components/lookout/sidebar/SidebarTabJobDetails.tsx
+++ b/internal/lookoutui/src/components/lookout/sidebar/SidebarTabJobDetails.tsx
@@ -19,6 +19,7 @@ export const SidebarTabJobDetails = ({ job }: SidebarTabJobDetailsProps) => {
{ key: "Priority", value: job.priority.toString() },
{ key: "Run Count", value: job.runs.length.toString() },
...(job.cancelReason ? [{ key: "Cancel Reason", value: job.cancelReason, allowCopy: true }] : []),
+ ...(job.cancelUser ? [{ key: "Cancelled By", value: job.cancelUser, allowCopy: true }] : []),
]
return (
<>
diff --git a/internal/lookoutui/src/containers/lookout/JobsTableContainer.test.tsx b/internal/lookoutui/src/containers/lookout/JobsTableContainer.test.tsx
index 2f511c13af5..a4f3339e541 100644
--- a/internal/lookoutui/src/containers/lookout/JobsTableContainer.test.tsx
+++ b/internal/lookoutui/src/containers/lookout/JobsTableContainer.test.tsx
@@ -243,15 +243,15 @@ describe("JobsTableContainer", () => {
// Expand the first level
await expandRow("queue-1")
- await assertNumDataRowsShown(1 + 2)
+ await assertNumDataRowsShown(1 + 2, 1)
// Expand the second level
await expandRow("job-set-1")
- await assertNumDataRowsShown(1 + 2 + 2)
+ await assertNumDataRowsShown(1 + 2 + 2, 2)
// Expand the third level
await expandRow(JobState.Queued)
- await assertNumDataRowsShown(1 + 2 + 2 + 5)
+ await assertNumDataRowsShown(1 + 2 + 2 + 5, 2)
})
it("should reset currently-expanded if grouping changes", async () => {
@@ -627,12 +627,12 @@ describe("JobsTableContainer", () => {
await waitFor(() => expect(screen.queryAllByRole("progressbar").length).toBe(0))
}
- async function assertNumDataRowsShown(nDataRows: number) {
+ async function assertNumDataRowsShown(nDataRows: number, nExpandedGroupPaginationRows = 0) {
await waitFor(
async () => {
const table = await screen.findByRole("table", { name: "Jobs table" })
const rows = await within(table).findAllByRole("row")
- expect(rows.length).toBe(nDataRows + 1) // One row per data row, plus the header
+ expect(rows.length).toBe(nDataRows + nExpandedGroupPaginationRows + 1) // One row per data row, plus the pagination row for each expanded group, plus the header
},
{ timeout: 3000 },
)
diff --git a/internal/lookoutui/src/containers/lookout/JobsTableContainer.tsx b/internal/lookoutui/src/containers/lookout/JobsTableContainer.tsx
index ccf2fcdf4d8..2b81fb68543 100644
--- a/internal/lookoutui/src/containers/lookout/JobsTableContainer.tsx
+++ b/internal/lookoutui/src/containers/lookout/JobsTableContainer.tsx
@@ -43,7 +43,7 @@ import { Sidebar } from "../../components/lookout/sidebar/Sidebar"
import { useCustomSnackbar } from "../../hooks/useCustomSnackbar"
import { columnIsAggregatable, useFetchJobsTableData } from "../../hooks/useJobsTableData"
import { isJobGroupRow, JobRow, JobTableRow } from "../../models/jobsTableModels"
-import { Job, JobFilter, JobId, Match, SortDirection } from "../../models/lookoutModels"
+import { Job, JobFiltersWithExcludes, JobId, Match, SortDirection } from "../../models/lookoutModels"
import { ICordonService } from "../../services/lookout/CordonService"
import { CustomViewsService } from "../../services/lookout/CustomViewsService"
import { IGetJobInfoService } from "../../services/lookout/GetJobInfoService"
@@ -68,7 +68,7 @@ import {
} from "../../utils/jobsTableColumns"
import {
diffOfKeys,
- getFiltersForRows,
+ getFiltersForRowsSelection,
PendingData,
pendingDataForAllVisibleData,
updaterToValue,
@@ -641,12 +641,10 @@ export const JobsTableContainer = ({
}
const sideBarClose = () => setSidebarJobId(undefined)
- const selectedItemsFilters: JobFilter[][] = useMemo(() => {
- return Object.keys(selectedRows).map((rowId) => {
- const { rowIdPartsPath } = fromRowId(rowId as RowId)
- return getFiltersForRows(lookoutFilters, columnMatches, rowIdPartsPath)
- })
- }, [selectedRows, columnFilterState, lookoutFilters, allColumns])
+ const selectedItemsFilters: JobFiltersWithExcludes[] = useMemo(
+ () => getFiltersForRowsSelection(data, selectedRows, lookoutFilters, columnMatches),
+ [data, selectedRows, columnFilterState, lookoutFilters, allColumns],
+ )
const table = useReactTable({
data: data ?? [],
@@ -946,6 +944,7 @@ const JobsTableBody = ({
onClickRow,
onControlClickRow,
onShiftClickRow,
+ dataIsLoading,
),
)}
@@ -961,6 +960,7 @@ const recursiveRowRender = (
onClickRow: (row: Row) => void,
onControlClickRow: (row: Row) => void,
onShiftClickRow: (row: Row) => void,
+ dataIsLoading: boolean,
): JSX.Element => {
const original = row.original
const rowIsGroup = isJobGroupRow(original)
@@ -1002,26 +1002,35 @@ const recursiveRowRender = (
onClickRow,
onControlClickRow,
onShiftClickRow,
+ dataIsLoading,
),
)}
{/* Render pagination tools for this expanded row */}
- {rowIsGroup && row.getIsExpanded() && (original.subRowCount ?? 0) > original.subRows.length && (
-
-
-
-
-
- )}
+ {rowIsGroup &&
+ row.getIsExpanded() &&
+ (original.jobCount ?? 0) > original.subRows.length &&
+ original.subRows.length > 0 && (
+
+
+
+
+
+ )}
)
}
diff --git a/internal/lookoutui/src/hooks/useJobsTableData.ts b/internal/lookoutui/src/hooks/useJobsTableData.ts
index 7651b1aaa29..98fbc0491d3 100644
--- a/internal/lookoutui/src/hooks/useJobsTableData.ts
+++ b/internal/lookoutui/src/hooks/useJobsTableData.ts
@@ -22,7 +22,7 @@ import {
fetchJobs,
FetchRowRequest,
getFiltersForGroupedAnnotations,
- getFiltersForRows,
+ getFiltersForRow,
groupsToRows,
jobsToRows,
PendingData,
@@ -158,7 +158,7 @@ export const useFetchJobsTableData = ({
const expandedLevel = parentRowInfo ? parentRowInfo.rowIdPathFromRoot.length : 0
const isJobFetch = expandedLevel === groupingLevel
- const filterValues = getFiltersForRows(lookoutFilters, columnMatches, parentRowInfo?.rowIdPartsPath ?? [])
+ const filterValues = getFiltersForRow(lookoutFilters, columnMatches, parentRowInfo?.rowIdPartsPath ?? [])
const order = getOrder(lookoutOrder, isJobFetch)
const rowRequest: FetchRowRequest = {
filters: filterValues,
diff --git a/internal/lookoutui/src/models/lookoutModels.tsx b/internal/lookoutui/src/models/lookoutModels.tsx
index 675184b9939..3859ca32dcb 100644
--- a/internal/lookoutui/src/models/lookoutModels.tsx
+++ b/internal/lookoutui/src/models/lookoutModels.tsx
@@ -122,6 +122,7 @@ export type Job = {
lastActiveRunId?: string
lastTransitionTime: string
cancelReason?: string
+ cancelUser?: string
node?: string
cluster?: string
exitCode?: number
@@ -176,6 +177,11 @@ export type JobFilter = {
match: Match
}
+export interface JobFiltersWithExcludes {
+ jobFilters: JobFilter[]
+ excludesJobFilters: JobFilter[][]
+}
+
export type JobGroup = {
name: string
count: number
diff --git a/internal/lookoutui/src/utils/jobsDialogUtils.ts b/internal/lookoutui/src/utils/jobsDialogUtils.ts
index e56a6de77aa..8bf448e08a2 100644
--- a/internal/lookoutui/src/utils/jobsDialogUtils.ts
+++ b/internal/lookoutui/src/utils/jobsDialogUtils.ts
@@ -1,6 +1,6 @@
import _ from "lodash"
-import { Job, JobFilter } from "../models/lookoutModels"
+import { Job, JobFilter, JobFiltersWithExcludes } from "../models/lookoutModels"
import { IGetJobsService } from "../services/lookout/GetJobsService"
export const getAllJobsMatchingFilters = async (
@@ -29,12 +29,23 @@ export const getAllJobsMatchingFilters = async (
}
export const getUniqueJobsMatchingFilters = async (
- filtersGroups: JobFilter[][],
+ filtersGroups: JobFiltersWithExcludes[],
activeJobSets: boolean,
getJobsService: IGetJobsService,
): Promise => {
const jobsBySelectedItem = await Promise.all(
- filtersGroups.map(async (filters) => await getAllJobsMatchingFilters(filters, activeJobSets, getJobsService)),
+ filtersGroups.map(async ({ jobFilters, excludesJobFilters }) => {
+ const allMatchingJobs = await getAllJobsMatchingFilters(jobFilters, activeJobSets, getJobsService)
+ const excludedJobs = (
+ await Promise.all(
+ excludesJobFilters.map((excludeJobFilters) =>
+ getAllJobsMatchingFilters(excludeJobFilters, activeJobSets, getJobsService),
+ ),
+ )
+ ).flat()
+ const excludedJobIds = new Set(excludedJobs.map((job) => job.jobId))
+ return allMatchingJobs.filter((job) => !excludedJobIds.has(job.jobId))
+ }),
)
return _.uniqBy(jobsBySelectedItem.flat(), (job) => job.jobId)
}
diff --git a/internal/lookoutui/src/utils/jobsTableUtils.test.ts b/internal/lookoutui/src/utils/jobsTableUtils.test.ts
index 34f850eb3f9..c8549cd9d86 100644
--- a/internal/lookoutui/src/utils/jobsTableUtils.test.ts
+++ b/internal/lookoutui/src/utils/jobsTableUtils.test.ts
@@ -1,4 +1,8 @@
-import { diffOfKeys } from "./jobsTableUtils"
+import { StandardColumnId, toAnnotationColId } from "./jobsTableColumns"
+import { diffOfKeys, getFiltersForRowsSelection } from "./jobsTableUtils"
+import { RowId } from "./reactTableUtils"
+import { LookoutColumnFilter } from "../containers/lookout/JobsTableContainer"
+import { JobFilter, JobFiltersWithExcludes, JobState, Match } from "../models/lookoutModels"
describe("JobsTableUtils", () => {
describe("diffOfKeys", () => {
@@ -44,4 +48,304 @@ describe("JobsTableUtils", () => {
expect(removedKeys).toStrictEqual(["a", "b"])
})
})
+
+ describe("getFiltersForRowsSelection", () => {
+ const testColumnFilters: LookoutColumnFilter[] = [
+ {
+ id: StandardColumnId.Namespace,
+ value: "my-testing-",
+ },
+ { id: toAnnotationColId("testing.co.uk/abc"), value: "easy-as-123" },
+ ]
+
+ const testColumnMatches: Record = {
+ [StandardColumnId.Namespace]: Match.StartsWith,
+ [toAnnotationColId("testing.co.uk/abc")]: Match.Exact,
+ }
+
+ const expectedJobFiltersForColumns: JobFilter[] = [
+ {
+ isAnnotation: false,
+ field: StandardColumnId.Namespace,
+ value: "my-testing-",
+ match: Match.StartsWith,
+ },
+ {
+ isAnnotation: true,
+ field: "testing.co.uk/abc",
+ value: "easy-as-123",
+ match: Match.Exact,
+ },
+ ]
+
+ it("zero rows", () => {
+ const result = getFiltersForRowsSelection([], {}, testColumnFilters, testColumnMatches)
+ expect(result).toEqual([])
+ })
+
+ it("flat, ungrouped list", () => {
+ const allIds: RowId[] = ["jobId:000", "jobId:001", "jobId:002", "jobId:003"]
+
+ const result = getFiltersForRowsSelection(
+ allIds.map((rowId) => ({ rowId })),
+ {
+ "jobId:001": true,
+ "jobId:002": true,
+ },
+ testColumnFilters,
+ testColumnMatches,
+ )
+
+ const expected: JobFiltersWithExcludes[] = [
+ {
+ jobFilters: [
+ ...expectedJobFiltersForColumns,
+ {
+ field: StandardColumnId.JobID,
+ isAnnotation: false,
+ match: Match.Exact,
+ value: "001",
+ },
+ ],
+ excludesJobFilters: [],
+ },
+ {
+ jobFilters: [
+ ...expectedJobFiltersForColumns,
+ {
+ field: StandardColumnId.JobID,
+ isAnnotation: false,
+ match: Match.Exact,
+ value: "002",
+ },
+ ],
+ excludesJobFilters: [],
+ },
+ ]
+ expect(result).toEqual(expected)
+ })
+
+ it("single-level group, not expanded", () => {
+ const result = getFiltersForRowsSelection(
+ [
+ {
+ rowId: "queue:myqueue123",
+ isGroup: true,
+ groupedField: StandardColumnId.Queue,
+ subRows: [],
+ stateCounts: {
+ [JobState.Running]: 2,
+ [JobState.Succeeded]: 1,
+ },
+ },
+ ],
+ {
+ "queue:myqueue123": true,
+ },
+ testColumnFilters,
+ testColumnMatches,
+ )
+
+ const expected: JobFiltersWithExcludes[] = [
+ {
+ jobFilters: [
+ ...expectedJobFiltersForColumns,
+ {
+ field: StandardColumnId.Queue,
+ isAnnotation: false,
+ match: Match.Exact,
+ value: "myqueue123",
+ },
+ ],
+ excludesJobFilters: [],
+ },
+ ]
+ expect(result).toEqual(expected)
+ })
+
+ it("multi-level groups, some expanded", () => {
+ const result = getFiltersForRowsSelection(
+ [
+ {
+ rowId: "queue:q1",
+ isGroup: true,
+ groupedField: StandardColumnId.Queue,
+ subRows: [
+ {
+ rowId: "queue:q1>jobSet:js1",
+ isGroup: true,
+ groupedField: StandardColumnId.JobSet,
+ subRows: [
+ {
+ rowId: "queue:q1>jobSet:js1>state:RUNNING",
+ isGroup: true,
+ groupedField: StandardColumnId.State,
+ subRows: [{ rowId: "jobId:001" }, { rowId: "jobId:002" }],
+ stateCounts: {
+ [JobState.Running]: 4,
+ },
+ },
+ {
+ rowId: "queue:q1>jobSet:js1>state:FAILED",
+ isGroup: true,
+ groupedField: StandardColumnId.State,
+ subRows: [],
+ stateCounts: {
+ [JobState.Failed]: 4,
+ },
+ },
+ {
+ rowId: "queue:q1>jobSet:js1>state:CANCELLED",
+ isGroup: true,
+ groupedField: StandardColumnId.State,
+ subRows: [{ rowId: "jobId:009" }, { rowId: "jobId:010" }, { rowId: "jobId:011" }],
+ stateCounts: {
+ [JobState.Cancelled]: 3,
+ },
+ },
+ ],
+ stateCounts: {
+ [JobState.Running]: 4,
+ [JobState.Failed]: 4,
+ [JobState.Cancelled]: 3,
+ },
+ },
+ {
+ rowId: "queue:q1>jobSet:js2",
+ isGroup: true,
+ groupedField: StandardColumnId.JobSet,
+ subRows: [],
+ stateCounts: {
+ [JobState.Running]: 40,
+ [JobState.Succeeded]: 4,
+ },
+ },
+ {
+ rowId: "queue:q1>jobSet:js3",
+ isGroup: true,
+ groupedField: StandardColumnId.JobSet,
+ subRows: [],
+ stateCounts: {
+ [JobState.Preempted]: 12,
+ },
+ },
+ ],
+ stateCounts: {
+ [JobState.Running]: 44,
+ [JobState.Failed]: 4,
+ [JobState.Cancelled]: 3,
+ [JobState.Succeeded]: 4,
+ [JobState.Preempted]: 12,
+ },
+ },
+ ],
+ {
+ "queue:q1": true,
+ "queue:q1>jobSet:js1": true,
+ "queue:q1>jobSet:js1>state:RUNNING": true,
+ "jobId:002": true,
+ "queue:q1>jobSet:js1>state:FAILED": true,
+ "jobId:010": true,
+ "jobId:011": true,
+ "queue:q1>jobSet:js3": true,
+ },
+ testColumnFilters,
+ testColumnMatches,
+ )
+
+ const queueExpectedJobFilter = (queue: string): JobFilter => ({
+ field: StandardColumnId.Queue,
+ isAnnotation: false,
+ match: Match.Exact,
+ value: queue,
+ })
+
+ const jobSetExpectedJobFilter = (jobSet: string): JobFilter => ({
+ field: StandardColumnId.JobSet,
+ isAnnotation: false,
+ match: Match.Exact,
+ value: jobSet,
+ })
+
+ const jobStateExpectedJobFilter = (jobState: JobState): JobFilter => ({
+ field: StandardColumnId.State,
+ isAnnotation: false,
+ match: Match.Exact,
+ value: jobState,
+ })
+
+ const jobIdExpectedJobFilter = (jobId: string): JobFilter => ({
+ field: StandardColumnId.JobID,
+ isAnnotation: false,
+ match: Match.Exact,
+ value: jobId,
+ })
+
+ const expected: JobFiltersWithExcludes[] = [
+ {
+ jobFilters: [...expectedJobFiltersForColumns, queueExpectedJobFilter("q1")],
+ excludesJobFilters: [
+ [...expectedJobFiltersForColumns, queueExpectedJobFilter("q1"), jobSetExpectedJobFilter("js1")],
+ [...expectedJobFiltersForColumns, queueExpectedJobFilter("q1"), jobSetExpectedJobFilter("js2")],
+ [...expectedJobFiltersForColumns, queueExpectedJobFilter("q1"), jobSetExpectedJobFilter("js3")],
+ ],
+ },
+ {
+ jobFilters: [...expectedJobFiltersForColumns, queueExpectedJobFilter("q1"), jobSetExpectedJobFilter("js1")],
+ excludesJobFilters: [
+ [
+ ...expectedJobFiltersForColumns,
+ queueExpectedJobFilter("q1"),
+ jobSetExpectedJobFilter("js1"),
+ jobStateExpectedJobFilter(JobState.Running),
+ ],
+ [
+ ...expectedJobFiltersForColumns,
+ queueExpectedJobFilter("q1"),
+ jobSetExpectedJobFilter("js1"),
+ jobStateExpectedJobFilter(JobState.Failed),
+ ],
+ [
+ ...expectedJobFiltersForColumns,
+ queueExpectedJobFilter("q1"),
+ jobSetExpectedJobFilter("js1"),
+ jobStateExpectedJobFilter(JobState.Cancelled),
+ ],
+ ],
+ },
+ {
+ jobFilters: [
+ ...expectedJobFiltersForColumns,
+ queueExpectedJobFilter("q1"),
+ jobSetExpectedJobFilter("js1"),
+ jobStateExpectedJobFilter(JobState.Running),
+ ],
+ excludesJobFilters: [
+ [...expectedJobFiltersForColumns, jobIdExpectedJobFilter("001")],
+ [...expectedJobFiltersForColumns, jobIdExpectedJobFilter("002")],
+ ],
+ },
+ {
+ jobFilters: [...expectedJobFiltersForColumns, jobIdExpectedJobFilter("002")],
+ excludesJobFilters: [],
+ },
+ {
+ jobFilters: [
+ ...expectedJobFiltersForColumns,
+ queueExpectedJobFilter("q1"),
+ jobSetExpectedJobFilter("js1"),
+ jobStateExpectedJobFilter(JobState.Failed),
+ ],
+ excludesJobFilters: [],
+ },
+ { jobFilters: [...expectedJobFiltersForColumns, jobIdExpectedJobFilter("010")], excludesJobFilters: [] },
+ { jobFilters: [...expectedJobFiltersForColumns, jobIdExpectedJobFilter("011")], excludesJobFilters: [] },
+ {
+ jobFilters: [...expectedJobFiltersForColumns, queueExpectedJobFilter("q1"), jobSetExpectedJobFilter("js3")],
+ excludesJobFilters: [],
+ },
+ ]
+ expect(result).toEqual(expected)
+ })
+ })
})
diff --git a/internal/lookoutui/src/utils/jobsTableUtils.ts b/internal/lookoutui/src/utils/jobsTableUtils.ts
index d44623aa49b..965178d28db 100644
--- a/internal/lookoutui/src/utils/jobsTableUtils.ts
+++ b/internal/lookoutui/src/utils/jobsTableUtils.ts
@@ -1,4 +1,4 @@
-import { ExpandedStateList, Updater } from "@tanstack/react-table"
+import { ExpandedStateList, RowSelectionState, Updater } from "@tanstack/react-table"
import _ from "lodash"
import {
@@ -9,10 +9,10 @@ import {
isStandardColId,
VALID_COLUMN_MATCHES,
} from "./jobsTableColumns"
-import { findRowInData, RowId, RowIdParts, toRowId } from "./reactTableUtils"
+import { findRowInData, fromRowId, RowId, RowIdParts, toRowId } from "./reactTableUtils"
import { LookoutColumnFilter } from "../containers/lookout/JobsTableContainer"
-import { JobGroupRow, JobRow, JobTableRow } from "../models/jobsTableModels"
-import { Job, JobFilter, JobGroup, JobOrder, Match } from "../models/lookoutModels"
+import { isJobGroupRow, JobGroupRow, JobRow, JobTableRow } from "../models/jobsTableModels"
+import { Job, JobFilter, JobFiltersWithExcludes, JobGroup, JobOrder, Match } from "../models/lookoutModels"
import { IGetJobsService } from "../services/lookout/GetJobsService"
import { GroupedField, IGroupJobsService } from "../services/lookout/GroupJobsService"
@@ -70,7 +70,48 @@ export const matchForColumn = (columnId: string, columnMatches: Record,
+): JobFiltersWithExcludes[] =>
+ rows.reduce((acc, row) => {
+ const isRowSelected = selectedRows[row.rowId]
+ const filtersForRow = getFiltersForRow(columnFilters, columnMatches, fromRowId(row.rowId).rowIdPartsPath)
+
+ if (!isJobGroupRow(row) || row.subRows.length === 0) {
+ if (isRowSelected) {
+ acc.push({ jobFilters: filtersForRow, excludesJobFilters: [] })
+ }
+ return acc
+ }
+
+ if (isRowSelected) {
+ acc.push({
+ jobFilters: filtersForRow,
+ excludesJobFilters: row.subRows.map((subRow) =>
+ getFiltersForRow(columnFilters, columnMatches, fromRowId(subRow.rowId).rowIdPartsPath),
+ ),
+ })
+ }
+
+ acc.push(...getFiltersForRowsSelection(row.subRows, selectedRows, columnFilters, columnMatches))
+ return acc
+ }, [])
+
+export function getFiltersForRow(
filters: LookoutColumnFilter[],
columnMatches: Record,
expandedRowIdParts: RowIdParts[],
diff --git a/internal/scheduler/database/job_repository.go b/internal/scheduler/database/job_repository.go
index 6e68303611d..c0a65cb8b62 100644
--- a/internal/scheduler/database/job_repository.go
+++ b/internal/scheduler/database/job_repository.go
@@ -120,6 +120,7 @@ func (r *PostgresJobRepository) FetchInitialJobs(ctx *armadacontext.Context) ([]
Queued: row.Queued,
QueuedVersion: row.QueuedVersion,
CancelRequested: row.CancelRequested,
+ CancelUser: row.CancelUser,
Cancelled: row.Cancelled,
CancelByJobsetRequested: row.CancelByJobsetRequested,
Succeeded: row.Succeeded,
@@ -223,6 +224,7 @@ func (r *PostgresJobRepository) FetchJobUpdates(ctx *armadacontext.Context, jobS
return queries.SelectUpdatedJobs(ctx, SelectUpdatedJobsParams{Serial: from, Limit: r.batchSize})
})
updatedJobs = make([]Job, len(updatedJobRows))
+
for i, row := range updatedJobRows {
updatedJobs[i] = Job{
JobID: row.JobID,
@@ -237,6 +239,7 @@ func (r *PostgresJobRepository) FetchJobUpdates(ctx *armadacontext.Context, jobS
CancelRequested: row.CancelRequested,
Cancelled: row.Cancelled,
CancelByJobsetRequested: row.CancelByJobsetRequested,
+ CancelUser: row.CancelUser,
Succeeded: row.Succeeded,
Failed: row.Failed,
SchedulingInfo: row.SchedulingInfo,
diff --git a/internal/scheduler/database/job_repository_test.go b/internal/scheduler/database/job_repository_test.go
index 9f060d41620..93d21b30d24 100644
--- a/internal/scheduler/database/job_repository_test.go
+++ b/internal/scheduler/database/job_repository_test.go
@@ -431,6 +431,8 @@ func createTestJobs(numJobs int) ([]Job, []Job) {
dbJobs := make([]Job, numJobs)
expectedJobs := make([]Job, numJobs)
+ testCancelUser := "test-cancelling-user"
+
for i := 0; i < numJobs; i++ {
dbJobs[i] = Job{
JobID: util.NewULID(),
@@ -441,6 +443,7 @@ func createTestJobs(numJobs int) ([]Job, []Job) {
Queued: false,
QueuedVersion: 1,
CancelRequested: true,
+ CancelUser: &testCancelUser,
Cancelled: true,
CancelByJobsetRequested: true,
Succeeded: true,
@@ -458,6 +461,7 @@ func createTestJobs(numJobs int) ([]Job, []Job) {
Submitted: job.Submitted,
Priority: job.Priority,
CancelRequested: job.CancelRequested,
+ CancelUser: job.CancelUser,
Queued: job.Queued,
QueuedVersion: job.QueuedVersion,
CancelByJobsetRequested: true,
diff --git a/internal/scheduler/database/migrations/020_add_cancel_user.sql b/internal/scheduler/database/migrations/020_add_cancel_user.sql
new file mode 100644
index 00000000000..e69c397f7a9
--- /dev/null
+++ b/internal/scheduler/database/migrations/020_add_cancel_user.sql
@@ -0,0 +1,2 @@
+-- The (first) user who cancelled this job
+ALTER TABLE jobs ADD COLUMN cancel_user varchar(512) NULL;
\ No newline at end of file
diff --git a/internal/scheduler/database/models.go b/internal/scheduler/database/models.go
index 1da66b44d5c..5176a5f48d6 100644
--- a/internal/scheduler/database/models.go
+++ b/internal/scheduler/database/models.go
@@ -47,6 +47,7 @@ type Job struct {
Validated bool `db:"validated"`
Pools []string `db:"pools"`
BidPrice float64 `db:"bid_price"`
+ CancelUser *string `db:"cancel_user"`
}
type JobRunError struct {
diff --git a/internal/scheduler/database/query.sql.go b/internal/scheduler/database/query.sql.go
index 07140565c35..0bc9116a91b 100644
--- a/internal/scheduler/database/query.sql.go
+++ b/internal/scheduler/database/query.sql.go
@@ -142,32 +142,44 @@ func (q *Queries) MarkJobRunsSucceededById(ctx context.Context, runIds []string)
}
const markJobsCancelRequestedById = `-- name: MarkJobsCancelRequestedById :exec
-UPDATE jobs SET cancel_requested = true WHERE queue = $1 and job_set = $2 and job_id = ANY($3::text[]) and cancelled = false and succeeded = false and failed = false
+UPDATE jobs SET cancel_requested = true, cancel_user = $1 WHERE queue = $2 and job_set = $3 and job_id = ANY($4::text[]) and cancelled = false and succeeded = false and failed = false
`
type MarkJobsCancelRequestedByIdParams struct {
- Queue string `db:"queue"`
- JobSet string `db:"job_set"`
- JobIds []string `db:"job_ids"`
+ CancelUser *string `db:"cancel_user"`
+ Queue string `db:"queue"`
+ JobSet string `db:"job_set"`
+ JobIds []string `db:"job_ids"`
}
func (q *Queries) MarkJobsCancelRequestedById(ctx context.Context, arg MarkJobsCancelRequestedByIdParams) error {
- _, err := q.db.Exec(ctx, markJobsCancelRequestedById, arg.Queue, arg.JobSet, arg.JobIds)
+ _, err := q.db.Exec(ctx, markJobsCancelRequestedById,
+ arg.CancelUser,
+ arg.Queue,
+ arg.JobSet,
+ arg.JobIds,
+ )
return err
}
const markJobsCancelRequestedBySetAndQueuedState = `-- name: MarkJobsCancelRequestedBySetAndQueuedState :exec
-UPDATE jobs SET cancel_by_jobset_requested = true WHERE job_set = $1 and queue = $2 and queued = ANY($3::bool[]) and cancelled = false and succeeded = false and failed = false
+UPDATE jobs SET cancel_by_jobset_requested = true, cancel_user = $1 WHERE job_set = $2 and queue = $3 and queued = ANY($4::bool[]) and cancelled = false and succeeded = false and failed = false
`
type MarkJobsCancelRequestedBySetAndQueuedStateParams struct {
- JobSet string `db:"job_set"`
- Queue string `db:"queue"`
- QueuedStates []bool `db:"queued_states"`
+ CancelUser *string `db:"cancel_user"`
+ JobSet string `db:"job_set"`
+ Queue string `db:"queue"`
+ QueuedStates []bool `db:"queued_states"`
}
func (q *Queries) MarkJobsCancelRequestedBySetAndQueuedState(ctx context.Context, arg MarkJobsCancelRequestedBySetAndQueuedStateParams) error {
- _, err := q.db.Exec(ctx, markJobsCancelRequestedBySetAndQueuedState, arg.JobSet, arg.Queue, arg.QueuedStates)
+ _, err := q.db.Exec(ctx, markJobsCancelRequestedBySetAndQueuedState,
+ arg.CancelUser,
+ arg.JobSet,
+ arg.Queue,
+ arg.QueuedStates,
+ )
return err
}
@@ -387,7 +399,7 @@ func (q *Queries) SelectExecutorUpdateTimes(ctx context.Context) ([]SelectExecut
}
const selectInitialJobs = `-- name: SelectInitialJobs :many
-SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 AND cancelled = 'false' AND succeeded = 'false' and failed = 'false' ORDER BY serial LIMIT $2
+SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_user, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 AND cancelled = 'false' AND succeeded = 'false' and failed = 'false' ORDER BY serial LIMIT $2
`
type SelectInitialJobsParams struct {
@@ -406,6 +418,7 @@ type SelectInitialJobsRow struct {
QueuedVersion int32 `db:"queued_version"`
Validated bool `db:"validated"`
CancelRequested bool `db:"cancel_requested"`
+ CancelUser *string `db:"cancel_user"`
CancelByJobsetRequested bool `db:"cancel_by_jobset_requested"`
Cancelled bool `db:"cancelled"`
Succeeded bool `db:"succeeded"`
@@ -436,6 +449,7 @@ func (q *Queries) SelectInitialJobs(ctx context.Context, arg SelectInitialJobsPa
&i.QueuedVersion,
&i.Validated,
&i.CancelRequested,
+ &i.CancelUser,
&i.CancelByJobsetRequested,
&i.Cancelled,
&i.Succeeded,
@@ -513,7 +527,7 @@ func (q *Queries) SelectInitialRuns(ctx context.Context, arg SelectInitialRunsPa
}
const selectJobsByExecutorAndQueues = `-- name: SelectJobsByExecutorAndQueues :many
-SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price
+SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price, j.cancel_user
FROM runs jr
JOIN jobs j
ON jr.job_id = j.job_id
@@ -559,6 +573,7 @@ func (q *Queries) SelectJobsByExecutorAndQueues(ctx context.Context, arg SelectJ
&i.Validated,
&i.Pools,
&i.BidPrice,
+ &i.CancelUser,
); err != nil {
return nil, err
}
@@ -644,7 +659,7 @@ func (q *Queries) SelectLatestJobSerial(ctx context.Context) (int64, error) {
}
const selectLeasedJobsByQueue = `-- name: SelectLeasedJobsByQueue :many
-SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price
+SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price, j.cancel_user
FROM runs jr
JOIN jobs j
ON jr.job_id = j.job_id
@@ -689,6 +704,7 @@ func (q *Queries) SelectLeasedJobsByQueue(ctx context.Context, queue []string) (
&i.Validated,
&i.Pools,
&i.BidPrice,
+ &i.CancelUser,
); err != nil {
return nil, err
}
@@ -701,7 +717,7 @@ func (q *Queries) SelectLeasedJobsByQueue(ctx context.Context, queue []string) (
}
const selectNewJobs = `-- name: SelectNewJobs :many
-SELECT job_id, job_set, queue, user_id, submitted, groups, priority, queued, queued_version, cancel_requested, cancelled, cancel_by_jobset_requested, succeeded, failed, submit_message, scheduling_info, scheduling_info_version, serial, last_modified, validated, pools, bid_price FROM jobs WHERE serial > $1 ORDER BY serial LIMIT $2
+SELECT job_id, job_set, queue, user_id, submitted, groups, priority, queued, queued_version, cancel_requested, cancelled, cancel_by_jobset_requested, succeeded, failed, submit_message, scheduling_info, scheduling_info_version, serial, last_modified, validated, pools, bid_price, cancel_user FROM jobs WHERE serial > $1 ORDER BY serial LIMIT $2
`
type SelectNewJobsParams struct {
@@ -741,6 +757,7 @@ func (q *Queries) SelectNewJobs(ctx context.Context, arg SelectNewJobsParams) ([
&i.Validated,
&i.Pools,
&i.BidPrice,
+ &i.CancelUser,
); err != nil {
return nil, err
}
@@ -865,7 +882,7 @@ func (q *Queries) SelectNewRunsForJobs(ctx context.Context, arg SelectNewRunsFor
}
const selectPendingJobsByQueue = `-- name: SelectPendingJobsByQueue :many
-SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price
+SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price, j.cancel_user
FROM runs jr
JOIN jobs j
ON jr.job_id = j.job_id
@@ -910,6 +927,7 @@ func (q *Queries) SelectPendingJobsByQueue(ctx context.Context, queue []string)
&i.Validated,
&i.Pools,
&i.BidPrice,
+ &i.CancelUser,
); err != nil {
return nil, err
}
@@ -922,7 +940,7 @@ func (q *Queries) SelectPendingJobsByQueue(ctx context.Context, queue []string)
}
const selectQueuedJobsByQueue = `-- name: SelectQueuedJobsByQueue :many
-SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price
+SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price, j.cancel_user
FROM jobs j
WHERE j.queue = ANY($1::text[])
AND j.queued = true
@@ -960,6 +978,7 @@ func (q *Queries) SelectQueuedJobsByQueue(ctx context.Context, queue []string) (
&i.Validated,
&i.Pools,
&i.BidPrice,
+ &i.CancelUser,
); err != nil {
return nil, err
}
@@ -997,7 +1016,7 @@ func (q *Queries) SelectRunErrorsById(ctx context.Context, runIds []string) ([]J
}
const selectRunningJobsByQueue = `-- name: SelectRunningJobsByQueue :many
-SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price
+SELECT j.job_id, j.job_set, j.queue, j.user_id, j.submitted, j.groups, j.priority, j.queued, j.queued_version, j.cancel_requested, j.cancelled, j.cancel_by_jobset_requested, j.succeeded, j.failed, j.submit_message, j.scheduling_info, j.scheduling_info_version, j.serial, j.last_modified, j.validated, j.pools, j.bid_price, j.cancel_user
FROM runs jr
JOIN jobs j
ON jr.job_id = j.job_id
@@ -1042,6 +1061,7 @@ func (q *Queries) SelectRunningJobsByQueue(ctx context.Context, queue []string)
&i.Validated,
&i.Pools,
&i.BidPrice,
+ &i.CancelUser,
); err != nil {
return nil, err
}
@@ -1054,7 +1074,7 @@ func (q *Queries) SelectRunningJobsByQueue(ctx context.Context, queue []string)
}
const selectUpdatedJobs = `-- name: SelectUpdatedJobs :many
-SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 ORDER BY serial LIMIT $2
+SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_user, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 ORDER BY serial LIMIT $2
`
type SelectUpdatedJobsParams struct {
@@ -1073,6 +1093,7 @@ type SelectUpdatedJobsRow struct {
QueuedVersion int32 `db:"queued_version"`
Validated bool `db:"validated"`
CancelRequested bool `db:"cancel_requested"`
+ CancelUser *string `db:"cancel_user"`
CancelByJobsetRequested bool `db:"cancel_by_jobset_requested"`
Cancelled bool `db:"cancelled"`
Succeeded bool `db:"succeeded"`
@@ -1103,6 +1124,7 @@ func (q *Queries) SelectUpdatedJobs(ctx context.Context, arg SelectUpdatedJobsPa
&i.QueuedVersion,
&i.Validated,
&i.CancelRequested,
+ &i.CancelUser,
&i.CancelByJobsetRequested,
&i.Cancelled,
&i.Succeeded,
diff --git a/internal/scheduler/database/query/query.sql b/internal/scheduler/database/query/query.sql
index 61bfc5284f1..1be5fb8bbd4 100644
--- a/internal/scheduler/database/query/query.sql
+++ b/internal/scheduler/database/query/query.sql
@@ -5,22 +5,22 @@ SELECT * FROM jobs WHERE serial > $1 ORDER BY serial LIMIT $2;
SELECT job_id FROM jobs;
-- name: SelectInitialJobs :many
-SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 AND cancelled = 'false' AND succeeded = 'false' and failed = 'false' ORDER BY serial LIMIT $2;
+SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_user, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 AND cancelled = 'false' AND succeeded = 'false' and failed = 'false' ORDER BY serial LIMIT $2;
-- name: SelectUpdatedJobs :many
-SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 ORDER BY serial LIMIT $2;
+SELECT job_id, job_set, queue, priority, bid_price, submitted, queued, queued_version, validated, cancel_requested, cancel_user, cancel_by_jobset_requested, cancelled, succeeded, failed, scheduling_info, scheduling_info_version, pools, serial FROM jobs WHERE serial > $1 ORDER BY serial LIMIT $2;
-- name: UpdateJobPriorityByJobSet :exec
UPDATE jobs SET priority = $1 WHERE job_set = $2 and queue = $3 and cancelled = false and succeeded = false and failed = false;
-- name: MarkJobsCancelRequestedBySetAndQueuedState :exec
-UPDATE jobs SET cancel_by_jobset_requested = true WHERE job_set = sqlc.arg(job_set) and queue = sqlc.arg(queue) and queued = ANY(sqlc.arg(queued_states)::bool[]) and cancelled = false and succeeded = false and failed = false;
+UPDATE jobs SET cancel_by_jobset_requested = true, cancel_user = $1 WHERE job_set = sqlc.arg(job_set) and queue = sqlc.arg(queue) and queued = ANY(sqlc.arg(queued_states)::bool[]) and cancelled = false and succeeded = false and failed = false;
-- name: MarkJobsSucceededById :exec
UPDATE jobs SET succeeded = true WHERE job_id = ANY(sqlc.arg(job_ids)::text[]);
-- name: MarkJobsCancelRequestedById :exec
-UPDATE jobs SET cancel_requested = true WHERE queue = sqlc.arg(queue) and job_set = sqlc.arg(job_set) and job_id = ANY(sqlc.arg(job_ids)::text[]) and cancelled = false and succeeded = false and failed = false;
+UPDATE jobs SET cancel_requested = true, cancel_user = $1 WHERE queue = sqlc.arg(queue) and job_set = sqlc.arg(job_set) and job_id = ANY(sqlc.arg(job_ids)::text[]) and cancelled = false and succeeded = false and failed = false;
-- name: MarkJobsCancelledById :exec
UPDATE jobs SET cancelled = true WHERE job_id = ANY(sqlc.arg(job_ids)::text[]);
diff --git a/internal/scheduler/jobdb/job.go b/internal/scheduler/jobdb/job.go
index 0b55afc293f..6aca684a85a 100644
--- a/internal/scheduler/jobdb/job.go
+++ b/internal/scheduler/jobdb/job.go
@@ -58,6 +58,8 @@ type Job struct {
priorityClass types.PriorityClass
// True if the user has requested this job be cancelled
cancelRequested bool
+ // The (first) user who cancelled this job
+ cancelUser *string
// True if the user has requested this job's jobSet be cancelled
cancelByJobSetRequested bool
// True if the scheduler has cancelled the job
@@ -332,6 +334,9 @@ func (job *Job) Equal(other *Job) bool {
if job.cancelByJobSetRequested != other.cancelByJobSetRequested {
return false
}
+ if job.cancelUser != other.cancelUser {
+ return false
+ }
if job.cancelled != other.cancelled {
return false
}
@@ -564,6 +569,11 @@ func (job *Job) CancelRequested() bool {
return job.cancelRequested
}
+// CancelUser returns the first user who cancelled this job
+func (job *Job) CancelUser() *string {
+ return job.cancelUser
+}
+
// CancelByJobsetRequested returns true if the user has requested this job's jobSet be cancelled.
func (job *Job) CancelByJobsetRequested() bool {
return job.cancelByJobSetRequested
@@ -583,6 +593,13 @@ func (job *Job) WithCancelByJobsetRequested(cancelByJobsetRequested bool) *Job {
return j
}
+// WithCancelUser returns a copy of the job with the cancel user updated.
+func (job *Job) WithCancelUser(cancelUser *string) *Job {
+ j := copyJob(*job)
+ j.cancelUser = cancelUser
+ return j
+}
+
// Cancelled Returns true if the scheduler has cancelled the job
func (job *Job) Cancelled() bool {
return job.cancelled
diff --git a/internal/scheduler/jobdb/reconciliation.go b/internal/scheduler/jobdb/reconciliation.go
index 38c1ebb6b4d..37b36b10d10 100644
--- a/internal/scheduler/jobdb/reconciliation.go
+++ b/internal/scheduler/jobdb/reconciliation.go
@@ -127,6 +127,9 @@ func (jobDb *JobDb) reconcileJobDifferences(job *Job, jobRepoJob *database.Job,
if jobRepoJob.CancelByJobsetRequested && !job.CancelByJobsetRequested() {
job = job.WithCancelByJobsetRequested(true)
}
+ if jobRepoJob.CancelUser != nil && jobRepoJob.CancelUser != job.CancelUser() {
+ job = job.WithCancelUser(jobRepoJob.CancelUser)
+ }
if jobRepoJob.Cancelled && !job.Cancelled() {
job = job.WithCancelled(true)
}
diff --git a/internal/scheduler/metrics/cycle_metrics.go b/internal/scheduler/metrics/cycle_metrics.go
index 393db35e5a4..9fc00de43dc 100644
--- a/internal/scheduler/metrics/cycle_metrics.go
+++ b/internal/scheduler/metrics/cycle_metrics.go
@@ -29,7 +29,7 @@ type perCycleMetrics struct {
actualShare *prometheus.GaugeVec
fairnessError *prometheus.GaugeVec
demand *prometheus.GaugeVec
- cappedDemand *prometheus.GaugeVec
+ constrainedDemand *prometheus.GaugeVec
queueWeight *prometheus.GaugeVec
rawQueueWeight *prometheus.GaugeVec
gangsConsidered *prometheus.GaugeVec
@@ -88,10 +88,10 @@ func newPerCycleMetrics() *perCycleMetrics {
poolAndQueueLabels,
)
- cappedDemand := prometheus.NewGaugeVec(
+ constrainedDemand := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
- Name: prefix + "capped_demand",
- Help: "Capped Demand of each queue and pool. This differs from demand in that it limits demand by scheduling constraints",
+ Name: prefix + "constrained_demand",
+ Help: "Constrained demand of each queue and pool. This differs from demand in that it limits demand by scheduling constraints",
},
poolAndQueueLabels,
)
@@ -230,7 +230,7 @@ func newPerCycleMetrics() *perCycleMetrics {
adjustedFairShare: adjustedFairShare,
actualShare: actualShare,
demand: demand,
- cappedDemand: cappedDemand,
+ constrainedDemand: constrainedDemand,
queueWeight: queueWeight,
rawQueueWeight: rawQueueWeight,
fairnessError: fairnessError,
@@ -337,14 +337,14 @@ func (m *cycleMetrics) ReportSchedulerResult(result scheduling.SchedulerResult)
jobsConsidered := float64(len(queueContext.UnsuccessfulJobSchedulingContexts) + len(queueContext.SuccessfulJobSchedulingContexts))
actualShare := schedContext.FairnessCostProvider.UnweightedCostFromQueue(queueContext)
demand := schedContext.FairnessCostProvider.UnweightedCostFromAllocation(queueContext.Demand)
- cappedDemand := schedContext.FairnessCostProvider.UnweightedCostFromAllocation(queueContext.CappedDemand)
+ constrainedDemand := schedContext.FairnessCostProvider.UnweightedCostFromAllocation(queueContext.ConstrainedDemand)
currentCycle.consideredJobs.WithLabelValues(pool, queue).Set(jobsConsidered)
currentCycle.fairShare.WithLabelValues(pool, queue).Set(queueContext.FairShare)
currentCycle.adjustedFairShare.WithLabelValues(pool, queue).Set(queueContext.AdjustedFairShare)
currentCycle.actualShare.WithLabelValues(pool, queue).Set(actualShare)
currentCycle.demand.WithLabelValues(pool, queue).Set(demand)
- currentCycle.cappedDemand.WithLabelValues(pool, queue).Set(cappedDemand)
+ currentCycle.constrainedDemand.WithLabelValues(pool, queue).Set(constrainedDemand)
currentCycle.queueWeight.WithLabelValues(pool, queue).Set(queueContext.Weight)
currentCycle.rawQueueWeight.WithLabelValues(pool, queue).Set(queueContext.RawWeight)
}
@@ -425,7 +425,7 @@ func (m *cycleMetrics) describe(ch chan<- *prometheus.Desc) {
currentCycle.actualShare.Describe(ch)
currentCycle.fairnessError.Describe(ch)
currentCycle.demand.Describe(ch)
- currentCycle.cappedDemand.Describe(ch)
+ currentCycle.constrainedDemand.Describe(ch)
currentCycle.queueWeight.Describe(ch)
currentCycle.rawQueueWeight.Describe(ch)
currentCycle.gangsConsidered.Describe(ch)
@@ -459,7 +459,7 @@ func (m *cycleMetrics) collect(ch chan<- prometheus.Metric) {
currentCycle.actualShare.Collect(ch)
currentCycle.fairnessError.Collect(ch)
currentCycle.demand.Collect(ch)
- currentCycle.cappedDemand.Collect(ch)
+ currentCycle.constrainedDemand.Collect(ch)
currentCycle.rawQueueWeight.Collect(ch)
currentCycle.queueWeight.Collect(ch)
currentCycle.gangsConsidered.Collect(ch)
diff --git a/internal/scheduler/metrics/cycle_metrics_test.go b/internal/scheduler/metrics/cycle_metrics_test.go
index d6b4631d8aa..9e689ba644a 100644
--- a/internal/scheduler/metrics/cycle_metrics_test.go
+++ b/internal/scheduler/metrics/cycle_metrics_test.go
@@ -35,7 +35,7 @@ func TestReportStateTransitions(t *testing.T) {
"queue1": {
Allocated: cpu(10),
Demand: cpu(20),
- CappedDemand: cpu(15),
+ ConstrainedDemand: cpu(15),
AdjustedFairShare: 0.15,
SuccessfulJobSchedulingContexts: map[string]*context.JobSchedulingContext{
"job1": {
@@ -70,8 +70,8 @@ func TestReportStateTransitions(t *testing.T) {
demand := testutil.ToFloat64(m.latestCycleMetrics.Load().demand.WithLabelValues(poolQueue...))
assert.InDelta(t, 0.2, demand, epsilon, "demand")
- cappedDemand := testutil.ToFloat64(m.latestCycleMetrics.Load().cappedDemand.WithLabelValues(poolQueue...))
- assert.InDelta(t, 0.15, cappedDemand, epsilon, "cappedDemand")
+ constrainedDemand := testutil.ToFloat64(m.latestCycleMetrics.Load().constrainedDemand.WithLabelValues(poolQueue...))
+ assert.InDelta(t, 0.15, constrainedDemand, epsilon, "constrainedDemand")
adjustedFairShare := testutil.ToFloat64(m.latestCycleMetrics.Load().adjustedFairShare.WithLabelValues(poolQueue...))
assert.InDelta(t, 0.15, adjustedFairShare, epsilon, "adjustedFairShare")
@@ -121,7 +121,7 @@ func TestResetLeaderMetrics_ResetsLatestCycleMetrics(t *testing.T) {
testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec { return m.latestCycleMetrics.Load().actualShare }, poolQueueLabelValues)
testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec { return m.latestCycleMetrics.Load().fairnessError }, []string{"pool1"})
testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec { return m.latestCycleMetrics.Load().demand }, poolQueueLabelValues)
- testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec { return m.latestCycleMetrics.Load().cappedDemand }, poolQueueLabelValues)
+ testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec { return m.latestCycleMetrics.Load().constrainedDemand }, poolQueueLabelValues)
testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec { return m.latestCycleMetrics.Load().gangsConsidered }, poolQueueLabelValues)
testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec { return m.latestCycleMetrics.Load().gangsScheduled }, poolQueueLabelValues)
testResetGauge(func(metrics *cycleMetrics) *prometheus.GaugeVec {
@@ -157,7 +157,7 @@ func TestDisableLeaderMetrics(t *testing.T) {
m.latestCycleMetrics.Load().actualShare.WithLabelValues(poolQueueLabelValues...).Inc()
m.latestCycleMetrics.Load().fairnessError.WithLabelValues("pool1").Inc()
m.latestCycleMetrics.Load().demand.WithLabelValues(poolQueueLabelValues...).Inc()
- m.latestCycleMetrics.Load().cappedDemand.WithLabelValues(poolQueueLabelValues...).Inc()
+ m.latestCycleMetrics.Load().constrainedDemand.WithLabelValues(poolQueueLabelValues...).Inc()
m.scheduleCycleTime.Observe(float64(1000))
m.reconciliationCycleTime.Observe(float64(1000))
m.latestCycleMetrics.Load().gangsConsidered.WithLabelValues("pool1", "queue1").Inc()
diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go
index 23e73ade572..4849ea9f46a 100644
--- a/internal/scheduler/scheduler.go
+++ b/internal/scheduler/scheduler.go
@@ -649,15 +649,26 @@ func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, jo
})
}
job = job.WithQueued(false).WithoutTerminal().WithCancelled(true)
+ var cancelUser string
+ if cancelUserPtr := job.CancelUser(); cancelUserPtr != nil {
+ cancelUser = *cancelUserPtr
+ }
cancel := &armadaevents.EventSequence_Event{
Created: s.now(),
Event: &armadaevents.EventSequence_Event_CancelledJob{
- CancelledJob: &armadaevents.CancelledJob{JobId: job.Id()},
+ CancelledJob: &armadaevents.CancelledJob{
+ JobId: job.Id(),
+ CancelUser: cancelUser,
+ },
},
}
events = append(events, cancel)
} else if job.CancelByJobsetRequested() {
job = job.WithQueued(false).WithoutTerminal().WithCancelled(true)
+ var cancelUser string
+ if cancelUserPtr := job.CancelUser(); cancelUserPtr != nil {
+ cancelUser = *cancelUserPtr
+ }
cancelRequest := &armadaevents.EventSequence_Event{
Created: s.now(),
Event: &armadaevents.EventSequence_Event_CancelJob{
@@ -684,7 +695,10 @@ func (s *Scheduler) generateUpdateMessagesFromJob(ctx *armadacontext.Context, jo
cancel := &armadaevents.EventSequence_Event{
Created: s.now(),
Event: &armadaevents.EventSequence_Event_CancelledJob{
- CancelledJob: &armadaevents.CancelledJob{JobId: job.Id()},
+ CancelledJob: &armadaevents.CancelledJob{
+ JobId: job.Id(),
+ CancelUser: cancelUser,
+ },
},
}
events = append(events, cancel)
diff --git a/internal/scheduler/scheduling/context/queue.go b/internal/scheduler/scheduling/context/queue.go
index d26dbdf43b1..36332f81e48 100644
--- a/internal/scheduler/scheduling/context/queue.go
+++ b/internal/scheduler/scheduling/context/queue.go
@@ -39,9 +39,9 @@ type QueueSchedulingContext struct {
// Total demand from this queue. This is essentially the cumulative resources of all non-terminal jobs at the
// start of the scheduling cycle
Demand internaltypes.ResourceList
- // Capped Demand for this queue. This differs from Demand in that it takes into account any limits that we have
+ // Constrained demand for this queue. This differs from Demand in that it takes into account any constraints that we have
// placed on the queue
- CappedDemand internaltypes.ResourceList
+ ConstrainedDemand internaltypes.ResourceList
// Fair share is the weight of this queue over the sum of the weights of all queues
FairShare float64
// AdjustedFairShare modifies fair share such that queues that have a demand cost less than their fair share, have their fair share reallocated.
diff --git a/internal/scheduler/scheduling/context/scheduling.go b/internal/scheduler/scheduling/context/scheduling.go
index 2f73c8b5ea7..801a7d29492 100644
--- a/internal/scheduler/scheduling/context/scheduling.go
+++ b/internal/scheduler/scheduling/context/scheduling.go
@@ -94,7 +94,7 @@ func (sctx *SchedulingContext) AddQueueSchedulingContext(
rawWeight float64,
initialAllocatedByPriorityClass map[string]internaltypes.ResourceList,
demand internaltypes.ResourceList,
- cappedDemand internaltypes.ResourceList,
+ constrainedDemand internaltypes.ResourceList,
limiter *rate.Limiter,
) error {
if _, ok := sctx.QueueSchedulingContexts[queue]; ok {
@@ -125,7 +125,7 @@ func (sctx *SchedulingContext) AddQueueSchedulingContext(
Limiter: limiter,
Allocated: allocated,
Demand: demand,
- CappedDemand: cappedDemand,
+ ConstrainedDemand: constrainedDemand,
AllocatedByPriorityClass: initialAllocatedByPriorityClass,
ScheduledResourcesByPriorityClass: make(map[string]internaltypes.ResourceList),
EvictedResourcesByPriorityClass: make(map[string]internaltypes.ResourceList),
@@ -148,11 +148,18 @@ func (sctx *SchedulingContext) GetQueue(queue string) (fairness.Queue, bool) {
}
type queueInfo struct {
- queueName string
- adjustedShare float64
- fairShare float64
- weight float64
- cappedShare float64
+ // Name of queue
+ queueName string
+ // Demand of this queue, capped by constraints, as a fraction of total available resource.
+ constrainedDemandShare float64
+ // Weight of this queue, or zero if this queue already has all its constrainedDemandShare.
+ weight float64
+ // Plain fair share, just weight_of_this_queue / sum(weights_of_all_active_queues)
+ fairShare float64
+ // Fair share including this queue's proportion of any share unused by other queues.
+ uncappedAdjustedFairShare float64
+ // Fair share including this queue's proportion of any share unused by other queues, capped at this queue's constrainedDemandShare.
+ demandCappedAdjustedFairShare float64
}
// UpdateFairShares updates FairShare and AdjustedFairShare for every QueueSchedulingContext associated with the
@@ -163,7 +170,7 @@ func (sctx *SchedulingContext) UpdateFairShares() {
for _, q := range queueInfos {
qtx := sctx.QueueSchedulingContexts[q.queueName]
qtx.FairShare = q.fairShare
- qtx.AdjustedFairShare = q.adjustedShare
+ qtx.AdjustedFairShare = q.demandCappedAdjustedFairShare
}
}
@@ -172,14 +179,14 @@ func (sctx *SchedulingContext) CalculateTheoreticalShare(priority float64) float
qctxs := maps.Clone(sctx.QueueSchedulingContexts)
queueName := util.NewULID()
qctxs[queueName] = &QueueSchedulingContext{
- Queue: queueName,
- Weight: 1 / priority,
- CappedDemand: sctx.TotalResources.Factory().MakeAllMax(), // Infinite demand
+ Queue: queueName,
+ Weight: 1 / priority,
+ ConstrainedDemand: sctx.TotalResources.Factory().MakeAllMax(), // Infinite demand
}
queueInfos := sctx.updateFairShares(qctxs)
for _, q := range queueInfos {
if q.queueName == queueName {
- return q.adjustedShare
+ return q.demandCappedAdjustedFairShare
}
}
return math.NaN()
@@ -193,16 +200,17 @@ func (sctx *SchedulingContext) updateFairShares(qctxs map[string]*QueueSchedulin
queueInfos := make([]*queueInfo, 0, len(qctxs))
for queueName, qctx := range qctxs {
- cappedShare := 1.0
+ constrainedDemandShare := 1.0
if !sctx.TotalResources.AllZero() {
- cappedShare = sctx.FairnessCostProvider.UnweightedCostFromAllocation(qctx.CappedDemand)
+ constrainedDemandShare = sctx.FairnessCostProvider.UnweightedCostFromAllocation(qctx.ConstrainedDemand)
}
queueInfos = append(queueInfos, &queueInfo{
- queueName: queueName,
- adjustedShare: 0,
- fairShare: qctx.Weight / sctx.WeightSum,
- weight: qctx.Weight,
- cappedShare: cappedShare,
+ queueName: queueName,
+ demandCappedAdjustedFairShare: 0,
+ uncappedAdjustedFairShare: 0,
+ fairShare: qctx.Weight / sctx.WeightSum,
+ weight: qctx.Weight,
+ constrainedDemandShare: constrainedDemandShare,
})
}
@@ -223,14 +231,15 @@ func (sctx *SchedulingContext) updateFairShares(qctxs map[string]*QueueSchedulin
for _, q := range queueInfos {
if q.weight > 0 {
share := (q.weight / totalWeight) * unallocated
- q.adjustedShare += share
+ q.demandCappedAdjustedFairShare += share
+ q.uncappedAdjustedFairShare += share
}
}
unallocated = 0.0
for _, q := range queueInfos {
- excessShare := q.adjustedShare - q.cappedShare
+ excessShare := q.demandCappedAdjustedFairShare - q.constrainedDemandShare
if excessShare > 0 {
- q.adjustedShare = q.cappedShare
+ q.demandCappedAdjustedFairShare = q.constrainedDemandShare
q.weight = 0.0
unallocated += excessShare
}
diff --git a/internal/scheduler/scheduling/scheduling_algo.go b/internal/scheduler/scheduling/scheduling_algo.go
index 10b10a55a2b..9d6925dd532 100644
--- a/internal/scheduler/scheduling/scheduling_algo.go
+++ b/internal/scheduler/scheduling/scheduling_algo.go
@@ -488,7 +488,7 @@ func (l *FairSchedulingAlgo) constructSchedulingContext(
// To ensure fair share is computed only from active queues, i.e., queues with jobs queued or running.
continue
}
- cappedDemand := constraints.CapResources(queue.Name, demand)
+ constrainedDemand := constraints.CapResources(queue.Name, demand)
var allocatedByPriorityClass map[string]internaltypes.ResourceList
if allocationByQueueAndPriorityClass != nil {
@@ -523,7 +523,7 @@ func (l *FairSchedulingAlgo) constructSchedulingContext(
l.limiterByQueue[queue.Name] = queueLimiter
}
- if err := sctx.AddQueueSchedulingContext(queue.Name, weight, rawWeight, allocatedByPriorityClass, internaltypes.RlMapSumValues(demand), internaltypes.RlMapSumValues(cappedDemand), queueLimiter); err != nil {
+ if err := sctx.AddQueueSchedulingContext(queue.Name, weight, rawWeight, allocatedByPriorityClass, internaltypes.RlMapSumValues(demand), internaltypes.RlMapSumValues(constrainedDemand), queueLimiter); err != nil {
return nil, err
}
}
diff --git a/internal/scheduler/testfixtures/testfixtures.go b/internal/scheduler/testfixtures/testfixtures.go
index d5e8512fef8..57e4667d616 100644
--- a/internal/scheduler/testfixtures/testfixtures.go
+++ b/internal/scheduler/testfixtures/testfixtures.go
@@ -36,6 +36,7 @@ const (
TestQueue2 = "testQueue2"
TestPool = "testPool"
TestPool2 = "testPool2"
+ TestCancelUser = "canceluser"
AwayPool = "awayPool"
TestHostnameLabel = "kubernetes.io/hostname"
ClusterNameLabel = "cluster"
diff --git a/internal/scheduleringester/dbops.go b/internal/scheduleringester/dbops.go
index c511d717d01..62c27b33456 100644
--- a/internal/scheduleringester/dbops.go
+++ b/internal/scheduleringester/dbops.go
@@ -167,11 +167,17 @@ func discardNilOps(ops []DbOperation) []DbOperation {
}
type (
- InsertJobs map[string]*schedulerdb.Job
- InsertRuns map[string]*JobRunDetails
- UpdateJobSetPriorities map[JobSetKey]int64
- MarkJobSetsCancelRequested map[JobSetKey]*JobSetCancelAction
- MarkJobsCancelRequested map[JobSetKey][]string
+ InsertJobs map[string]*schedulerdb.Job
+ InsertRuns map[string]*JobRunDetails
+ UpdateJobSetPriorities map[JobSetKey]int64
+ MarkJobSetsCancelRequested struct {
+ cancelUser string
+ jobSets map[JobSetKey]*JobSetCancelAction
+ }
+ MarkJobsCancelRequested struct {
+ cancelUser string
+ jobIds map[JobSetKey][]string
+ }
MarkJobsCancelled map[string]time.Time
MarkJobsSucceeded map[string]bool
MarkJobsFailed map[string]bool
@@ -211,7 +217,7 @@ func (a UpdateJobSetPriorities) AffectsJobSet(queue string, jobSet string) bool
}
func (a MarkJobSetsCancelRequested) AffectsJobSet(queue string, jobSet string) bool {
- _, ok := a[JobSetKey{queue: queue, jobSet: jobSet}]
+ _, ok := a.jobSets[JobSetKey{queue: queue, jobSet: jobSet}]
return ok
}
@@ -228,11 +234,33 @@ func (a UpdateJobSetPriorities) Merge(b DbOperation) bool {
}
func (a MarkJobSetsCancelRequested) Merge(b DbOperation) bool {
- return mergeInMap(a, b)
+ switch op := b.(type) {
+ case MarkJobSetsCancelRequested:
+ if a.cancelUser != op.cancelUser {
+ return false
+ }
+ maps.Copy(a.jobSets, op.jobSets)
+ return true
+ }
+ return false
}
func (a MarkJobsCancelRequested) Merge(b DbOperation) bool {
- return mergeListMaps(a, b)
+ switch op := b.(type) {
+ case MarkJobsCancelRequested:
+ if a.cancelUser != op.cancelUser {
+ return false
+ }
+ for k, v := range op.jobIds {
+ if _, present := a.jobIds[k]; present {
+ a.jobIds[k] = append(a.jobIds[k], v...)
+ } else {
+ a.jobIds[k] = v
+ }
+ }
+ return true
+ }
+ return false
}
func (a MarkRunsForJobPreemptRequested) Merge(b DbOperation) bool {
@@ -434,11 +462,11 @@ func (a UpdateJobSetPriorities) CanBeAppliedBefore(b DbOperation) bool {
}
func (a MarkJobSetsCancelRequested) CanBeAppliedBefore(b DbOperation) bool {
- return !definesJobInSet(a, b) && !definesRunInSet(a, b)
+ return !definesJobInSet(a.jobSets, b) && !definesRunInSet(a.jobSets, b)
}
func (a MarkJobsCancelRequested) CanBeAppliedBefore(b DbOperation) bool {
- return !definesJobInSet(a, b) && !definesRunInSet(a, b)
+ return !definesJobInSet(a.jobIds, b) && !definesRunInSet(a.jobIds, b)
}
func (a MarkRunsForJobPreemptRequested) CanBeAppliedBefore(b DbOperation) bool {
diff --git a/internal/scheduleringester/dbops_test.go b/internal/scheduleringester/dbops_test.go
index 4424cd6b786..6a7b210a2fc 100644
--- a/internal/scheduleringester/dbops_test.go
+++ b/internal/scheduleringester/dbops_test.go
@@ -179,20 +179,50 @@ func TestDbOperationOptimisation(t *testing.T) {
&UpdateJobPriorities{JobReprioritiseKey{JobSetKey{queue: testQueueName, jobSet: "set1"}, 4}, []string{jobIds[2]}}, // 5
}},
"MarkJobSetsCancelRequested": {N: 3, Ops: []DbOperation{
- InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}}, // 1
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}}, // 2
- InsertJobs{jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"}}, // 3
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set2"}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}}, // 3
- InsertJobs{jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1"}}, // 3
+ InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}}, // 1
+ MarkJobSetsCancelRequested{
+ cancelUser: f.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set1"}: {cancelQueued: true, cancelLeased: true},
+ },
+ }, // 2
+ InsertJobs{jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"}}, // 3
+ MarkJobSetsCancelRequested{
+ cancelUser: f.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set2"}: {cancelQueued: true, cancelLeased: true},
+ },
+ }, // 3
+ InsertJobs{jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1"}}, // 3
}},
"MarkJobSetsCancelRequested, MarkJobsCancelRequested": {N: 4, Ops: []DbOperation{
- InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}}, // 1
- InsertJobs{jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"}}, // 1
- MarkJobsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[0]}}, // 2 // 2
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}}, // 3
- InsertJobs{jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1"}}, // 4
- MarkJobsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[1]}}, // 4 // 4
- MarkJobsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[2]}}, // 4 // 4
+ InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}}, // 1
+ InsertJobs{jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"}}, // 1
+ MarkJobsCancelRequested{
+ cancelUser: f.CancelUser,
+ jobIds: map[JobSetKey][]string{
+ {queue: testQueueName, jobSet: "set1"}: {jobIds[0]},
+ },
+ }, // 2
+ MarkJobSetsCancelRequested{
+ cancelUser: f.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set1"}: {cancelQueued: true, cancelLeased: true},
+ },
+ }, // 3
+ InsertJobs{jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1"}}, // 4
+ MarkJobsCancelRequested{
+ cancelUser: f.CancelUser,
+ jobIds: map[JobSetKey][]string{
+ {queue: testQueueName, jobSet: "set1"}: {jobIds[1]},
+ },
+ }, // 4
+ MarkJobsCancelRequested{
+ cancelUser: f.CancelUser,
+ jobIds: map[JobSetKey][]string{
+ {queue: testQueueName, jobSet: "set1"}: {jobIds[2]},
+ },
+ }, // 4
}},
"MarkRunsForJobPreemptRequested": {N: 2, Ops: []DbOperation{
InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}}, // 1
@@ -341,7 +371,12 @@ func TestInsertJobRequestCancel(t *testing.T) {
}
// Cancel one job set.
- ops = append(ops, MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}})
+ ops = append(ops, MarkJobSetsCancelRequested{
+ cancelUser: f.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set1"}: {cancelQueued: true, cancelLeased: true},
+ },
+ })
// Submit some more jobs to both job sets.
for i := 0; i < 2; i++ {
@@ -442,15 +477,16 @@ func (db *mockDb) apply(op DbOperation) error {
}
}
case MarkJobSetsCancelRequested:
- for jobSetKey := range o {
+ for jobSetKey := range o.jobSets {
for _, job := range db.Jobs {
if job.JobSet == jobSetKey.jobSet && job.Queue == jobSetKey.queue {
job.CancelRequested = true
+ job.CancelUser = &o.cancelUser
}
}
}
case MarkJobsCancelRequested:
- for jobSetKey, jobIds := range o {
+ for jobSetKey, jobIds := range o.jobIds {
for _, jobId := range jobIds {
job, ok := db.Jobs[jobId]
if !ok {
@@ -458,6 +494,7 @@ func (db *mockDb) apply(op DbOperation) error {
}
if job.JobSet == jobSetKey.jobSet && job.Queue == jobSetKey.queue {
job.CancelRequested = true
+ job.CancelUser = &o.cancelUser
}
}
}
diff --git a/internal/scheduleringester/instructions.go b/internal/scheduleringester/instructions.go
index ef732e84b13..e0c351a28c8 100644
--- a/internal/scheduleringester/instructions.go
+++ b/internal/scheduleringester/instructions.go
@@ -337,10 +337,13 @@ func (c *JobSetEventsInstructionConverter) handleReprioritiseJobSet(reprioritise
func (c *JobSetEventsInstructionConverter) handleCancelJob(cancelJob *armadaevents.CancelJob, meta eventSequenceCommon) ([]DbOperation, error) {
return []DbOperation{MarkJobsCancelRequested{
- JobSetKey{
- queue: meta.queue,
- jobSet: meta.jobset,
- }: []string{cancelJob.JobId},
+ cancelUser: meta.user,
+ jobIds: map[JobSetKey][]string{
+ {
+ queue: meta.queue,
+ jobSet: meta.jobset,
+ }: {cancelJob.JobId},
+ },
}}, nil
}
@@ -349,12 +352,15 @@ func (c *JobSetEventsInstructionConverter) handleCancelJobSet(cancelJobSet *arma
cancelLeased := len(cancelJobSet.States) == 0 || slices.Contains(cancelJobSet.States, armadaevents.JobState_PENDING) || slices.Contains(cancelJobSet.States, armadaevents.JobState_RUNNING)
return []DbOperation{MarkJobSetsCancelRequested{
- JobSetKey{
- queue: meta.queue,
- jobSet: meta.jobset,
- }: &JobSetCancelAction{
- cancelQueued: cancelQueued,
- cancelLeased: cancelLeased,
+ cancelUser: meta.user,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {
+ queue: meta.queue,
+ jobSet: meta.jobset,
+ }: {
+ cancelQueued: cancelQueued,
+ cancelLeased: cancelLeased,
+ },
},
}}, nil
}
diff --git a/internal/scheduleringester/instructions_test.go b/internal/scheduleringester/instructions_test.go
index 8ed1fcf5f51..d51d729b48a 100644
--- a/internal/scheduleringester/instructions_test.go
+++ b/internal/scheduleringester/instructions_test.go
@@ -146,31 +146,56 @@ func TestConvertEventSequence(t *testing.T) {
"JobCancelRequested": {
events: []*armadaevents.EventSequence_Event{f.JobCancelRequested},
expected: []DbOperation{
- MarkJobsCancelRequested{JobSetKey{queue: f.Queue, jobSet: f.JobsetName}: {f.JobId}},
+ MarkJobsCancelRequested{
+ cancelUser: f.UserId,
+ jobIds: map[JobSetKey][]string{
+ {queue: f.Queue, jobSet: f.JobsetName}: {f.JobId},
+ },
+ },
},
},
"JobSetCancelRequested": {
events: []*armadaevents.EventSequence_Event{f.JobSetCancelRequested},
expected: []DbOperation{
- MarkJobSetsCancelRequested{JobSetKey{queue: f.Queue, jobSet: f.JobsetName}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}},
+ MarkJobSetsCancelRequested{
+ cancelUser: f.UserId,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: f.Queue, jobSet: f.JobsetName}: {cancelQueued: true, cancelLeased: true},
+ },
+ },
},
},
"JobSetCancelRequested - Queued only": {
events: []*armadaevents.EventSequence_Event{f.JobSetCancelRequestedWithStateFilter(armadaevents.JobState_QUEUED)},
expected: []DbOperation{
- MarkJobSetsCancelRequested{JobSetKey{queue: f.Queue, jobSet: f.JobsetName}: &JobSetCancelAction{cancelQueued: true, cancelLeased: false}},
+ MarkJobSetsCancelRequested{
+ cancelUser: f.UserId,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: f.Queue, jobSet: f.JobsetName}: {cancelQueued: true, cancelLeased: false},
+ },
+ },
},
},
"JobSetCancelRequested - Pending only": {
events: []*armadaevents.EventSequence_Event{f.JobSetCancelRequestedWithStateFilter(armadaevents.JobState_PENDING)},
expected: []DbOperation{
- MarkJobSetsCancelRequested{JobSetKey{queue: f.Queue, jobSet: f.JobsetName}: &JobSetCancelAction{cancelQueued: false, cancelLeased: true}},
+ MarkJobSetsCancelRequested{
+ cancelUser: f.UserId,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: f.Queue, jobSet: f.JobsetName}: {cancelQueued: false, cancelLeased: true},
+ },
+ },
},
},
"JobSetCancelRequested - Running only": {
events: []*armadaevents.EventSequence_Event{f.JobSetCancelRequestedWithStateFilter(armadaevents.JobState_RUNNING)},
expected: []DbOperation{
- MarkJobSetsCancelRequested{JobSetKey{queue: f.Queue, jobSet: f.JobsetName}: &JobSetCancelAction{cancelQueued: false, cancelLeased: true}},
+ MarkJobSetsCancelRequested{
+ cancelUser: f.UserId,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: f.Queue, jobSet: f.JobsetName}: {cancelQueued: false, cancelLeased: true},
+ },
+ },
},
},
"JobCancelled": {
@@ -213,7 +238,10 @@ func TestConvertEventSequence(t *testing.T) {
"multiple events": {
events: []*armadaevents.EventSequence_Event{f.JobSetCancelRequested, f.Running, f.JobSucceeded},
expected: []DbOperation{
- MarkJobSetsCancelRequested{JobSetKey{queue: f.Queue, jobSet: f.JobsetName}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}},
+ MarkJobSetsCancelRequested{
+ cancelUser: f.UserId,
+ jobSets: map[JobSetKey]*JobSetCancelAction{{queue: f.Queue, jobSet: f.JobsetName}: {cancelQueued: true, cancelLeased: true}},
+ },
MarkRunsRunning{f.RunId: f.BaseTime},
MarkJobsSucceeded{f.JobId: true},
},
diff --git a/internal/scheduleringester/schedulerdb.go b/internal/scheduleringester/schedulerdb.go
index 01929560929..4f7925c5888 100644
--- a/internal/scheduleringester/schedulerdb.go
+++ b/internal/scheduleringester/schedulerdb.go
@@ -160,7 +160,7 @@ func (s *SchedulerDb) WriteDbOp(ctx *armadacontext.Context, tx pgx.Tx, op DbOper
return errors.WithStack(err)
}
case MarkJobSetsCancelRequested:
- for jobSetInfo, cancelDetails := range o {
+ for jobSetInfo, cancelDetails := range o.jobSets {
queuedStatesToCancel := make([]bool, 0, 2)
if cancelDetails.cancelQueued {
// Cancel all jobs in a queued state
@@ -176,6 +176,7 @@ func (s *SchedulerDb) WriteDbOp(ctx *armadacontext.Context, tx pgx.Tx, op DbOper
Queue: jobSetInfo.queue,
JobSet: jobSetInfo.jobSet,
QueuedStates: queuedStatesToCancel,
+ CancelUser: &o.cancelUser,
},
)
if err != nil {
@@ -183,11 +184,12 @@ func (s *SchedulerDb) WriteDbOp(ctx *armadacontext.Context, tx pgx.Tx, op DbOper
}
}
case MarkJobsCancelRequested:
- for key, value := range o {
+ for key, value := range o.jobIds {
params := schedulerdb.MarkJobsCancelRequestedByIdParams{
- Queue: key.queue,
- JobSet: key.jobSet,
- JobIds: value,
+ Queue: key.queue,
+ JobSet: key.jobSet,
+ JobIds: value,
+ CancelUser: &o.cancelUser,
}
err := queries.MarkJobsCancelRequestedById(ctx, params)
if err != nil {
diff --git a/internal/scheduleringester/schedulerdb_test.go b/internal/scheduleringester/schedulerdb_test.go
index 95b9d70a3b4..4efac47361c 100644
--- a/internal/scheduleringester/schedulerdb_test.go
+++ b/internal/scheduleringester/schedulerdb_test.go
@@ -133,7 +133,12 @@ func TestWriteOps(t *testing.T) {
jobIds[3]: &schedulerdb.Job{JobID: jobIds[3], Queue: testQueueName, JobSet: "set2"},
jobIds[4]: &schedulerdb.Job{JobID: jobIds[4], Queue: "queue-2", JobSet: "set1"},
},
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: &JobSetCancelAction{cancelLeased: true, cancelQueued: true}},
+ MarkJobSetsCancelRequested{
+ cancelUser: testfixtures.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set1"}: {cancelLeased: true, cancelQueued: true},
+ },
+ },
}},
"MarkJobSetsCancelRequested - Queued only": {Ops: []DbOperation{
InsertJobs{
@@ -142,7 +147,12 @@ func TestWriteOps(t *testing.T) {
jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1", Queued: false},
jobIds[3]: &schedulerdb.Job{JobID: jobIds[3], Queue: testQueueName, JobSet: "set2", Queued: false},
},
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: &JobSetCancelAction{cancelLeased: false, cancelQueued: true}},
+ MarkJobSetsCancelRequested{
+ cancelUser: testfixtures.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set1"}: {cancelLeased: false, cancelQueued: true},
+ },
+ },
}},
"MarkJobSetsCancelRequested - Leased only": {Ops: []DbOperation{
InsertJobs{
@@ -151,7 +161,12 @@ func TestWriteOps(t *testing.T) {
jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1", Queued: false},
jobIds[3]: &schedulerdb.Job{JobID: jobIds[3], Queue: testQueueName, JobSet: "set2", Queued: false},
},
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: &JobSetCancelAction{cancelLeased: true, cancelQueued: false}},
+ MarkJobSetsCancelRequested{
+ cancelUser: testfixtures.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set1"}: {cancelLeased: true, cancelQueued: false},
+ },
+ },
}},
"MarkJobsCancelRequested": {Ops: []DbOperation{
InsertJobs{
@@ -161,8 +176,11 @@ func TestWriteOps(t *testing.T) {
jobIds[3]: &schedulerdb.Job{JobID: jobIds[3], Queue: testQueueName, JobSet: "set2"},
},
MarkJobsCancelRequested{
- JobSetKey{queue: testQueueName, jobSet: "set1"}: []string{jobIds[0]},
- JobSetKey{queue: testQueueName, jobSet: "set2"}: []string{jobIds[1]},
+ cancelUser: testfixtures.CancelUser,
+ jobIds: map[JobSetKey][]string{
+ {queue: testQueueName, jobSet: "set1"}: {jobIds[0]},
+ {queue: testQueueName, jobSet: "set2"}: {jobIds[1]},
+ },
},
}},
"MarkJobsCancelled": {Ops: []DbOperation{
@@ -441,11 +459,21 @@ func TestScoping(t *testing.T) {
},
"Multiple DbOp jobSet scope": {
Ops: []DbOperation{
- InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}}, // 1
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set1"}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}}, // 2
- InsertJobs{jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"}}, // 3
- MarkJobSetsCancelRequested{JobSetKey{queue: testQueueName, jobSet: "set2"}: &JobSetCancelAction{cancelQueued: true, cancelLeased: true}}, // 3
- InsertJobs{jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1"}}, // 3
+ InsertJobs{jobIds[0]: &schedulerdb.Job{JobID: jobIds[0], Queue: testQueueName, JobSet: "set1"}}, // 1
+ MarkJobSetsCancelRequested{
+ cancelUser: testfixtures.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set1"}: {cancelQueued: true, cancelLeased: true},
+ },
+ }, // 2
+ InsertJobs{jobIds[1]: &schedulerdb.Job{JobID: jobIds[1], Queue: testQueueName, JobSet: "set1"}}, // 3
+ MarkJobSetsCancelRequested{
+ cancelUser: testfixtures.CancelUser,
+ jobSets: map[JobSetKey]*JobSetCancelAction{
+ {queue: testQueueName, jobSet: "set2"}: {cancelQueued: true, cancelLeased: true},
+ }, // 3
+ },
+ InsertJobs{jobIds[2]: &schedulerdb.Job{JobID: jobIds[2], Queue: testQueueName, JobSet: "set1"}}, // 3
},
Scope: JobSetEventsLockKey,
Error: false,
@@ -642,7 +670,7 @@ func assertOpSuccess(t *testing.T, schedulerDb *SchedulerDb, serials map[string]
numChanged := 0
jobIds := make([]string, 0)
for _, job := range jobs {
- if _, ok := expected[JobSetKey{queue: job.Queue, jobSet: job.JobSet}]; ok {
+ if _, ok := expected.jobSets[JobSetKey{queue: job.Queue, jobSet: job.JobSet}]; ok {
assert.True(t, job.CancelByJobsetRequested)
numChanged++
jobIds = append(jobIds, job.JobID)
@@ -657,13 +685,13 @@ func assertOpSuccess(t *testing.T, schedulerDb *SchedulerDb, serials map[string]
numChanged := 0
jobIds := make([]string, 0)
for _, job := range jobs {
- if _, ok := expected[JobSetKey{queue: job.Queue, jobSet: job.JobSet}]; ok {
+ if _, ok := expected.jobIds[JobSetKey{queue: job.Queue, jobSet: job.JobSet}]; ok {
assert.True(t, job.CancelRequested)
numChanged++
jobIds = append(jobIds, job.JobID)
}
}
- assert.Equal(t, len(expected), numChanged)
+ assert.Equal(t, len(expected.jobIds), numChanged)
case MarkRunsForJobPreemptRequested:
jobs, err := selectNewJobs(ctx, 0)
if err != nil {
diff --git a/internal/server/event/conversion/conversions.go b/internal/server/event/conversion/conversions.go
index 7db8eaf72d4..a3ca58e410d 100644
--- a/internal/server/event/conversion/conversions.go
+++ b/internal/server/event/conversion/conversions.go
@@ -470,6 +470,7 @@ func FromInternalResourceUtilisation(queueName string, jobSetName string, time t
PodName: e.GetResourceInfo().GetObjectMeta().GetName(),
PodNamespace: e.GetResourceInfo().GetObjectMeta().GetNamespace(),
TotalCumulativeUsage: e.TotalCumulativeUsage,
+ AvgResourcesForPeriod: e.AvgResourcesForPeriod,
}
return []*api.EventMessage{
diff --git a/internal/server/event/conversion/conversions_test.go b/internal/server/event/conversion/conversions_test.go
index 8cc18b136db..94c1b68c507 100644
--- a/internal/server/event/conversion/conversions_test.go
+++ b/internal/server/event/conversion/conversions_test.go
@@ -738,6 +738,10 @@ func TestConvertResourceUtilisation(t *testing.T) {
"cpu": resourcePointer("3.0"),
"mem": resourcePointer("200Gi"),
},
+ AvgResourcesForPeriod: map[string]*resource.Quantity{
+ "cpu": resourcePointer("2.5"),
+ "mem": resourcePointer("150Gi"),
+ },
},
},
}
@@ -764,6 +768,10 @@ func TestConvertResourceUtilisation(t *testing.T) {
"cpu": resourcePointer("3.0"),
"mem": resourcePointer("200Gi"),
},
+ AvgResourcesForPeriod: map[string]*resource.Quantity{
+ "cpu": resourcePointer("2.5"),
+ "mem": resourcePointer("150Gi"),
+ },
},
},
},
diff --git a/internal/server/queryapi/database/models.go b/internal/server/queryapi/database/models.go
index 1ccae7f8544..d63ad953db1 100644
--- a/internal/server/queryapi/database/models.go
+++ b/internal/server/queryapi/database/models.go
@@ -31,6 +31,7 @@ type Job struct {
Namespace *string `db:"namespace"`
Annotations []byte `db:"annotations"`
ExternalJobUri *string `db:"external_job_uri"`
+ CancelUser *string `db:"cancel_user"`
}
type JobDeduplication struct {
diff --git a/internal/server/queryapi/database/query.sql b/internal/server/queryapi/database/query.sql
index 54d9347cf97..f66e20d8ecc 100644
--- a/internal/server/queryapi/database/query.sql
+++ b/internal/server/queryapi/database/query.sql
@@ -2,7 +2,7 @@
SELECT job_id, state FROM job WHERE job_id = ANY(sqlc.arg(job_ids)::text[]);
-- name: GetJobDetails :many
-SELECT j.job_id, j.queue, j.jobset, j.namespace, j.state, j.submitted, j.cancelled, j.cancel_reason, j.last_transition_time, j.latest_run_id, COALESCE(js.job_spec, j.job_spec) FROM job j left join job_spec js on j.job_id = js.job_id WHERE j.job_id = ANY(sqlc.arg(job_ids)::text[]);
+SELECT j.job_id, j.queue, j.jobset, j.namespace, j.state, j.submitted, j.cancelled, j.cancel_reason, j.cancel_user, j.last_transition_time, j.latest_run_id, COALESCE(js.job_spec, j.job_spec) FROM job j left join job_spec js on j.job_id = js.job_id WHERE j.job_id = ANY(sqlc.arg(job_ids)::text[]);
-- name: GetJobRunsByRunIds :many
SELECT * FROM job_run WHERE run_id = ANY(sqlc.arg(run_ids)::text[]);
diff --git a/internal/server/queryapi/database/query.sql.go b/internal/server/queryapi/database/query.sql.go
index 0bbd8d30eda..584fa4167bf 100644
--- a/internal/server/queryapi/database/query.sql.go
+++ b/internal/server/queryapi/database/query.sql.go
@@ -12,7 +12,7 @@ import (
)
const getJobDetails = `-- name: GetJobDetails :many
-SELECT j.job_id, j.queue, j.jobset, j.namespace, j.state, j.submitted, j.cancelled, j.cancel_reason, j.last_transition_time, j.latest_run_id, COALESCE(js.job_spec, j.job_spec) FROM job j left join job_spec js on j.job_id = js.job_id WHERE j.job_id = ANY($1::text[])
+SELECT j.job_id, j.queue, j.jobset, j.namespace, j.state, j.submitted, j.cancelled, j.cancel_reason, j.cancel_user, j.last_transition_time, j.latest_run_id, COALESCE(js.job_spec, j.job_spec) FROM job j left join job_spec js on j.job_id = js.job_id WHERE j.job_id = ANY($1::text[])
`
type GetJobDetailsRow struct {
@@ -24,6 +24,7 @@ type GetJobDetailsRow struct {
Submitted pgtype.Timestamp `db:"submitted"`
Cancelled pgtype.Timestamp `db:"cancelled"`
CancelReason *string `db:"cancel_reason"`
+ CancelUser *string `db:"cancel_user"`
LastTransitionTime pgtype.Timestamp `db:"last_transition_time"`
LatestRunID *string `db:"latest_run_id"`
JobSpec []byte `db:"job_spec"`
@@ -47,6 +48,7 @@ func (q *Queries) GetJobDetails(ctx context.Context, jobIds []string) ([]GetJobD
&i.Submitted,
&i.Cancelled,
&i.CancelReason,
+ &i.CancelUser,
&i.LastTransitionTime,
&i.LatestRunID,
&i.JobSpec,
diff --git a/internal/server/queryapi/database/sql.yaml b/internal/server/queryapi/database/sql.yaml
index a9ac9dc2069..649c7933b93 100644
--- a/internal/server/queryapi/database/sql.yaml
+++ b/internal/server/queryapi/database/sql.yaml
@@ -1,7 +1,7 @@
# Compile with "sqlc generate -f internal/server/queryapi/database/sql.yaml" from the project root directory.
version: 2
sql:
- - schema: "../../../lookoutv2/schema/migrations"
+ - schema: "../../../lookout/schema/migrations"
queries: "query.sql"
engine: "postgresql"
gen:
diff --git a/internal/server/queryapi/query_api.go b/internal/server/queryapi/query_api.go
index d18f9223767..23dc6d7e3f5 100644
--- a/internal/server/queryapi/query_api.go
+++ b/internal/server/queryapi/query_api.go
@@ -98,6 +98,7 @@ func (q *QueryApi) GetJobDetails(ctx context.Context, req *api.JobDetailsRequest
SubmittedTs: DbTimeToTimestamp(row.Submitted),
CancelTs: DbTimeToTimestamp(row.Cancelled),
CancelReason: NilStringToString(row.CancelReason),
+ CancelUser: NilStringToString(row.CancelUser),
LastTransitionTs: DbTimeToTimestamp(row.LastTransitionTime),
LatestRunId: NilStringToString(row.LatestRunID),
JobSpec: jobSpec,
diff --git a/internal/server/queryapi/query_api_test.go b/internal/server/queryapi/query_api_test.go
index f7178426260..31d0ab5c851 100644
--- a/internal/server/queryapi/query_api_test.go
+++ b/internal/server/queryapi/query_api_test.go
@@ -436,6 +436,7 @@ func newJob(jobId string, state int16, latestRunId string) database.Job {
PriorityClass: nil,
LatestRunID: pointer.String(latestRunId),
CancelReason: nil,
+ CancelUser: nil,
Namespace: pointer.String("testNamespace"),
Annotations: annotations,
ExternalJobUri: pointer.String("external-job-uri"),
@@ -482,6 +483,7 @@ func newJobDetails(jobId string, state api.JobState, latestRunId string, runs ..
SubmittedTs: baseTimestamp,
CancelTs: nil,
CancelReason: "",
+ CancelUser: "",
LastTransitionTs: baseTimestamp,
LatestRunId: latestRunId,
JobSpec: nil,
diff --git a/magefiles/developer.go b/magefiles/developer.go
index 3b770870c76..525d9b4112f 100644
--- a/magefiles/developer.go
+++ b/magefiles/developer.go
@@ -25,9 +25,9 @@ var defaultComponents = []string{
"executor",
"binoculars",
"eventingester",
- "lookoutv2",
- "lookoutingesterv2",
- "lookoutv2-migration",
+ "lookout",
+ "lookoutingester",
+ "lookout-migration",
}
var allComponents = append(
@@ -53,7 +53,7 @@ func getComponentsList() []string {
func RunMigrations() error {
migrations := []string{
"scheduler-migration",
- "lookoutv2-migration",
+ "lookout-migration",
}
command := append([]string{"compose", "up", "-d"}, migrations...)
return dockerRun(command...)
diff --git a/magefiles/main.go b/magefiles/main.go
index bef541b263f..ba422edbb3d 100644
--- a/magefiles/main.go
+++ b/magefiles/main.go
@@ -152,7 +152,16 @@ func KindTeardown() {
// Generate scheduler SQL.
func Sql() error {
mg.Deps(sqlcCheck)
- return sqlcRun("generate", "-f", "internal/scheduler/database/sql.yaml")
+
+ if err := sqlcRun("generate", "-f", "internal/scheduler/database/sql.yaml"); err != nil {
+ return err
+ }
+
+ if err := sqlcRun("generate", "-f", "internal/server/queryapi/database/sql.yaml"); err != nil {
+ return err
+ }
+
+ return nil
}
// Generate Helm documentation.
@@ -321,7 +330,7 @@ func Generate() error {
// CI Image to build
func BuildCI() error {
- ciImage := []string{"bundle", "lookout-bundle", "server", "executor", "armadactl", "testsuite", "lookoutv2", "lookoutingesterv2", "eventingester", "scheduler", "scheduleringester", "binoculars"}
+ ciImage := []string{"bundle", "lookout-bundle", "server", "executor", "armadactl", "testsuite", "lookout", "lookoutingester", "eventingester", "scheduler", "scheduleringester", "binoculars"}
err := goreleaserMinimalRelease(ciImage...)
if err != nil {
return err
diff --git a/magefiles/proto.go b/magefiles/proto.go
index 5753f181642..193511c8061 100644
--- a/magefiles/proto.go
+++ b/magefiles/proto.go
@@ -132,7 +132,7 @@ func protoGenerate() error {
err = sh.Run(
"swagger", "generate", "spec",
"-m", "-o", "pkg/api/api.swagger.definitions.json",
- "-x", "internal/lookoutv2",
+ "-x", "internal/lookout",
)
if err != nil {
return err
diff --git a/pkg/api/api.swagger.go b/pkg/api/api.swagger.go
index 43ad4e68d03..5d185170b61 100644
--- a/pkg/api/api.swagger.go
+++ b/pkg/api/api.swagger.go
@@ -1022,6 +1022,9 @@ func SwaggerJsonTemplate() string {
" \"type\": \"string\",\n" +
" \"format\": \"date-time\"\n" +
" },\n" +
+ " \"cancelUser\": {\n" +
+ " \"type\": \"string\"\n" +
+ " },\n" +
" \"jobId\": {\n" +
" \"type\": \"string\"\n" +
" },\n" +
@@ -1914,6 +1917,12 @@ func SwaggerJsonTemplate() string {
" \"apiJobUtilisationEvent\": {\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
+ " \"AvgResourcesForPeriod\": {\n" +
+ " \"type\": \"object\",\n" +
+ " \"additionalProperties\": {\n" +
+ " \"$ref\": \"#/definitions/resourceQuantity\"\n" +
+ " }\n" +
+ " },\n" +
" \"MaxResourcesForPeriod\": {\n" +
" \"type\": \"object\",\n" +
" \"additionalProperties\": {\n" +
diff --git a/pkg/api/api.swagger.json b/pkg/api/api.swagger.json
index a4fc33ff558..eb3c7504251 100644
--- a/pkg/api/api.swagger.json
+++ b/pkg/api/api.swagger.json
@@ -1011,6 +1011,9 @@
"type": "string",
"format": "date-time"
},
+ "cancelUser": {
+ "type": "string"
+ },
"jobId": {
"type": "string"
},
@@ -1903,6 +1906,12 @@
"apiJobUtilisationEvent": {
"type": "object",
"properties": {
+ "AvgResourcesForPeriod": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/definitions/resourceQuantity"
+ }
+ },
"MaxResourcesForPeriod": {
"type": "object",
"additionalProperties": {
diff --git a/pkg/api/event.pb.go b/pkg/api/event.pb.go
index df8053c7add..2653d1ea79c 100644
--- a/pkg/api/event.pb.go
+++ b/pkg/api/event.pb.go
@@ -1403,6 +1403,7 @@ type JobUtilisationEvent struct {
PodName string `protobuf:"bytes,10,opt,name=pod_name,json=podName,proto3" json:"podName,omitempty"`
PodNamespace string `protobuf:"bytes,11,opt,name=pod_namespace,json=podNamespace,proto3" json:"podNamespace,omitempty"`
TotalCumulativeUsage map[string]*resource.Quantity `protobuf:"bytes,12,rep,name=total_cumulative_usage,json=totalCumulativeUsage,proto3" json:"totalCumulativeUsage,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ AvgResourcesForPeriod map[string]*resource.Quantity `protobuf:"bytes,13,rep,name=AvgResourcesForPeriod,proto3" json:"AvgResourcesForPeriod,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (m *JobUtilisationEvent) Reset() { *m = JobUtilisationEvent{} }
@@ -1522,6 +1523,13 @@ func (m *JobUtilisationEvent) GetTotalCumulativeUsage() map[string]*resource.Qua
return nil
}
+func (m *JobUtilisationEvent) GetAvgResourcesForPeriod() map[string]*resource.Quantity {
+ if m != nil {
+ return m.AvgResourcesForPeriod
+ }
+ return nil
+}
+
type JobReprioritizingEvent 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"`
@@ -2551,6 +2559,7 @@ func init() {
proto.RegisterType((*JobPreemptedEvent)(nil), "api.JobPreemptedEvent")
proto.RegisterType((*JobSucceededEvent)(nil), "api.JobSucceededEvent")
proto.RegisterType((*JobUtilisationEvent)(nil), "api.JobUtilisationEvent")
+ proto.RegisterMapType((map[string]*resource.Quantity)(nil), "api.JobUtilisationEvent.AvgResourcesForPeriodEntry")
proto.RegisterMapType((map[string]*resource.Quantity)(nil), "api.JobUtilisationEvent.MaxResourcesForPeriodEntry")
proto.RegisterMapType((map[string]*resource.Quantity)(nil), "api.JobUtilisationEvent.TotalCumulativeUsageEntry")
proto.RegisterType((*JobReprioritizingEvent)(nil), "api.JobReprioritizingEvent")
@@ -2568,151 +2577,152 @@ func init() {
func init() { proto.RegisterFile("pkg/api/event.proto", fileDescriptor_7758595c3bb8cf56) }
var fileDescriptor_7758595c3bb8cf56 = []byte{
- // 2292 bytes of a gzipped FileDescriptorProto
+ // 2320 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcd, 0x6f, 0x1b, 0xc7,
0x15, 0xf7, 0x52, 0xfc, 0x1c, 0xea, 0x73, 0x2c, 0xc9, 0x6b, 0x3a, 0xd6, 0x0a, 0x34, 0xd0, 0x2a,
- 0x46, 0x4c, 0xa6, 0x74, 0x52, 0x04, 0x46, 0x81, 0xc2, 0x54, 0x94, 0x44, 0x6a, 0x5c, 0x3b, 0x94,
- 0x8d, 0xa4, 0x45, 0x00, 0x76, 0x3f, 0x46, 0xd2, 0x4a, 0xe4, 0xce, 0x66, 0x3f, 0x6c, 0x2b, 0x46,
- 0x2e, 0xed, 0xa5, 0x87, 0xa2, 0xe9, 0x07, 0x7a, 0x2b, 0xda, 0xa2, 0xc7, 0x02, 0xbd, 0xf4, 0x2f,
- 0xe8, 0xa1, 0x28, 0x7a, 0x0c, 0x92, 0x4b, 0x4f, 0x44, 0x61, 0x17, 0x29, 0xc0, 0x53, 0xef, 0xbd,
- 0x14, 0xf3, 0x66, 0x76, 0x39, 0xb3, 0xa6, 0x60, 0x59, 0xf9, 0x32, 0x14, 0x9e, 0x6c, 0xfd, 0xde,
- 0xbc, 0x37, 0x6f, 0xde, 0xfe, 0x66, 0xe6, 0xcd, 0xbc, 0x21, 0x3a, 0xeb, 0x1f, 0xec, 0x36, 0x4d,
- 0xdf, 0x6d, 0x92, 0xbb, 0xc4, 0x8b, 0x1a, 0x7e, 0x40, 0x23, 0x8a, 0xa7, 0x4c, 0xdf, 0xad, 0x19,
- 0xbb, 0x94, 0xee, 0xf6, 0x48, 0x13, 0x20, 0x2b, 0xde, 0x69, 0x46, 0x6e, 0x9f, 0x84, 0x91, 0xd9,
- 0xf7, 0x79, 0xab, 0xda, 0x62, 0xa2, 0x1a, 0xc6, 0x56, 0xdf, 0x8d, 0xb2, 0xe8, 0x1e, 0x31, 0x7b,
- 0xd1, 0x9e, 0x40, 0x2f, 0x64, 0x8d, 0x91, 0xbe, 0x1f, 0x1d, 0x0a, 0xe1, 0x73, 0x42, 0xc8, 0xb4,
- 0x4c, 0xcf, 0xa3, 0x91, 0x19, 0xb9, 0xd4, 0x0b, 0x85, 0xf4, 0xa5, 0x83, 0x57, 0xc2, 0x86, 0x4b,
- 0x99, 0xb4, 0x6f, 0xda, 0x7b, 0xae, 0x47, 0x82, 0xc3, 0x66, 0xd2, 0x49, 0x40, 0x42, 0x1a, 0x07,
- 0x36, 0x69, 0xee, 0x12, 0x8f, 0x04, 0x66, 0x44, 0x1c, 0xae, 0x55, 0xff, 0x6d, 0x0e, 0x2d, 0x6c,
- 0x51, 0x6b, 0x1b, 0x5c, 0x8b, 0x88, 0xb3, 0xc1, 0x86, 0x87, 0x2f, 0xa3, 0xe2, 0x3e, 0xb5, 0xba,
- 0xae, 0xa3, 0x6b, 0xab, 0xda, 0x5a, 0xa5, 0x7d, 0x76, 0x38, 0x30, 0xe6, 0xf6, 0xa9, 0xb5, 0xe9,
- 0xbc, 0x40, 0xfb, 0x6e, 0x04, 0x4e, 0x75, 0x0a, 0x00, 0xe0, 0x97, 0x10, 0x62, 0x6d, 0x43, 0x12,
- 0xb1, 0xf6, 0x39, 0x68, 0xbf, 0x3c, 0x1c, 0x18, 0x78, 0x9f, 0x5a, 0xdb, 0x24, 0x52, 0x54, 0xca,
- 0x09, 0x86, 0x9f, 0x47, 0x85, 0xf7, 0x62, 0x12, 0x13, 0x7d, 0x6a, 0xd4, 0x01, 0x00, 0x72, 0x07,
- 0x00, 0xe0, 0xef, 0xa1, 0x92, 0x1d, 0x10, 0xe6, 0xb3, 0x9e, 0x5f, 0xd5, 0xd6, 0xaa, 0xad, 0x5a,
- 0x83, 0x07, 0xa2, 0x91, 0x44, 0xa9, 0x71, 0x3b, 0x09, 0x79, 0x7b, 0x69, 0x38, 0x30, 0x16, 0x44,
- 0x73, 0xc9, 0x54, 0x62, 0x01, 0x5f, 0x41, 0x53, 0xfb, 0xd4, 0xd2, 0x0b, 0x60, 0xa8, 0xdc, 0x30,
- 0x7d, 0xb7, 0xb1, 0x45, 0xad, 0xf6, 0xc2, 0x70, 0x60, 0xcc, 0xec, 0x53, 0x4b, 0x52, 0x61, 0xed,
- 0xea, 0x43, 0x0d, 0xcd, 0x6e, 0x51, 0xeb, 0x2d, 0xe6, 0xc8, 0x69, 0x8f, 0x4d, 0xfd, 0x8f, 0x39,
- 0x18, 0xec, 0x9b, 0xc4, 0x0c, 0x4f, 0x3f, 0x11, 0xbe, 0x8d, 0x90, 0xdd, 0x8b, 0xc3, 0x88, 0x04,
- 0xcc, 0xdb, 0x02, 0x74, 0x7e, 0x6e, 0x38, 0x30, 0xce, 0x0a, 0x54, 0x71, 0xb7, 0x92, 0x82, 0xf5,
- 0x5f, 0xe6, 0xd1, 0x52, 0x12, 0xa4, 0x0e, 0x89, 0xe2, 0xc0, 0x9b, 0xc4, 0xea, 0x88, 0x58, 0xe1,
- 0x17, 0x50, 0x31, 0x20, 0x66, 0x48, 0x3d, 0xbd, 0x08, 0x3a, 0x8b, 0xc3, 0x81, 0x31, 0xcf, 0x11,
- 0x49, 0x41, 0xb4, 0xc1, 0xdf, 0x45, 0x33, 0x07, 0xb1, 0x45, 0x02, 0x8f, 0x44, 0x24, 0x64, 0x1d,
- 0x95, 0x40, 0xa9, 0x36, 0x1c, 0x18, 0xcb, 0x23, 0x81, 0xd2, 0xd7, 0xb4, 0x8c, 0x33, 0x37, 0x7d,
- 0xea, 0x74, 0xbd, 0xb8, 0x6f, 0x91, 0x40, 0x2f, 0xaf, 0x6a, 0x6b, 0x05, 0xee, 0xa6, 0x4f, 0x9d,
- 0xef, 0x03, 0x28, 0xbb, 0x99, 0x82, 0xac, 0xe3, 0x20, 0xf6, 0xba, 0x66, 0x04, 0x22, 0xe2, 0xe8,
- 0x95, 0x55, 0x6d, 0xad, 0xcc, 0x3b, 0x0e, 0x62, 0xef, 0x7a, 0x82, 0xcb, 0x1d, 0xcb, 0x78, 0xfd,
- 0xbf, 0x1a, 0x5a, 0x4c, 0x38, 0xb1, 0x71, 0xdf, 0x77, 0x83, 0xd3, 0xbf, 0x56, 0x7c, 0x98, 0x47,
- 0x73, 0x5b, 0xd4, 0xba, 0x45, 0x3c, 0xc7, 0xf5, 0x76, 0x27, 0x13, 0x60, 0xfc, 0x04, 0x78, 0x8c,
- 0xd2, 0xc5, 0xcf, 0x44, 0xe9, 0xd2, 0xb1, 0x29, 0xfd, 0x22, 0x2a, 0x83, 0x9e, 0xd9, 0x27, 0x30,
- 0x11, 0x2a, 0x7c, 0x88, 0xac, 0x81, 0xd9, 0x97, 0xa3, 0x55, 0x12, 0x10, 0x73, 0x35, 0xd1, 0x08,
- 0x7d, 0xd3, 0x26, 0x30, 0x09, 0x84, 0xab, 0xa2, 0x0d, 0xe0, 0xb2, 0xab, 0x32, 0x5e, 0xff, 0x1b,
- 0x67, 0x44, 0x27, 0xf6, 0xbc, 0x09, 0x23, 0xbe, 0x38, 0x46, 0x5c, 0x45, 0x15, 0x8f, 0x3a, 0x84,
- 0x7f, 0xda, 0xd2, 0x28, 0x4a, 0x0c, 0xcc, 0x7c, 0xdb, 0x72, 0x82, 0x9d, 0x78, 0x65, 0x94, 0x69,
- 0x54, 0x39, 0x19, 0x8d, 0xd0, 0x53, 0xd2, 0xe8, 0x2f, 0x45, 0x74, 0x76, 0x8b, 0x5a, 0x9b, 0xde,
- 0x6e, 0x40, 0xc2, 0x70, 0xd3, 0xdb, 0xa1, 0x13, 0x2a, 0x9d, 0x36, 0x2a, 0xa1, 0x93, 0x51, 0xa9,
- 0xfa, 0x74, 0x54, 0xc2, 0x0f, 0xd0, 0x82, 0xcb, 0x69, 0xd4, 0x35, 0x1d, 0x87, 0xfd, 0x4b, 0x42,
- 0xbd, 0xb2, 0x3a, 0xb5, 0x56, 0x6d, 0x35, 0x92, 0xcc, 0x3f, 0xcb, 0xb3, 0x86, 0x00, 0xae, 0x27,
- 0x0a, 0x1b, 0x5e, 0x14, 0x1c, 0xb6, 0x57, 0x86, 0x03, 0xa3, 0xe6, 0x66, 0x44, 0x52, 0xc7, 0xf3,
- 0x59, 0x59, 0xed, 0x00, 0x2d, 0x8d, 0x35, 0x85, 0x2f, 0xa1, 0xa9, 0x03, 0x72, 0x08, 0x2c, 0x2e,
- 0xf0, 0x73, 0xc7, 0x01, 0x39, 0x94, 0xcf, 0x1d, 0x07, 0xe4, 0x90, 0x71, 0xf1, 0xae, 0xd9, 0x8b,
- 0x89, 0x20, 0x2f, 0x70, 0x11, 0x00, 0x99, 0x8b, 0x00, 0x5c, 0xcb, 0xbd, 0xa2, 0xd5, 0xff, 0x97,
- 0x47, 0xfa, 0x16, 0xb5, 0xee, 0x78, 0xa6, 0xd5, 0x23, 0xb7, 0xe9, 0xb6, 0xbd, 0x47, 0x9c, 0xb8,
- 0x47, 0x26, 0x33, 0xe7, 0x99, 0xc8, 0x4b, 0x95, 0x79, 0x56, 0x3e, 0xd1, 0x3c, 0xab, 0x3c, 0xc3,
- 0xf3, 0xac, 0xfe, 0x71, 0x09, 0xce, 0x8d, 0xaf, 0x99, 0x6e, 0x6f, 0x72, 0x16, 0xfa, 0x7c, 0x38,
- 0xf7, 0x2e, 0x42, 0xe4, 0xbe, 0x1b, 0x75, 0x6d, 0xea, 0x90, 0x50, 0x2f, 0xc1, 0x9a, 0x55, 0x4f,
- 0xd6, 0x2c, 0x29, 0xd0, 0x8d, 0x8d, 0xfb, 0x6e, 0xb4, 0xce, 0x1a, 0xf1, 0x75, 0xea, 0x3c, 0xf3,
- 0x84, 0x24, 0xd8, 0xc8, 0xb0, 0xae, 0x75, 0x2a, 0x29, 0xfc, 0x38, 0xa3, 0xcb, 0x9f, 0x85, 0xd1,
- 0x95, 0x13, 0x31, 0x1a, 0x9d, 0x88, 0xd1, 0x33, 0x27, 0x63, 0xf4, 0xec, 0x53, 0xee, 0x1c, 0x0e,
- 0xc2, 0x36, 0xf5, 0x22, 0xd3, 0xf5, 0x48, 0xd0, 0x0d, 0x23, 0x33, 0x8a, 0xd9, 0xd6, 0x51, 0x85,
- 0xcf, 0xb0, 0x08, 0x9f, 0x61, 0x3d, 0x11, 0x6f, 0x83, 0xb4, 0x6d, 0x0c, 0x07, 0xc6, 0x05, 0x5b,
- 0x05, 0x95, 0x1d, 0x62, 0xe1, 0x31, 0x21, 0x7e, 0x19, 0x15, 0x6c, 0x33, 0x0e, 0x89, 0x3e, 0xbd,
- 0xaa, 0xad, 0xcd, 0xb6, 0x10, 0x37, 0xcc, 0x10, 0x4e, 0x67, 0x10, 0xca, 0x74, 0x06, 0xa0, 0xe6,
- 0xa0, 0x59, 0xf5, 0xab, 0xcb, 0x5b, 0x4a, 0xe5, 0x78, 0x5b, 0x4a, 0xe1, 0x89, 0x5b, 0xca, 0x27,
- 0x39, 0x84, 0xd9, 0x01, 0x2f, 0x20, 0x4c, 0xf4, 0x35, 0xc8, 0xe8, 0x5f, 0x46, 0x95, 0x80, 0xbc,
- 0x17, 0x93, 0x30, 0xa2, 0x81, 0x3c, 0xaf, 0x53, 0x50, 0x66, 0x67, 0x0a, 0x3e, 0xdd, 0xbc, 0xae,
- 0xff, 0x26, 0x0f, 0xd7, 0xad, 0x22, 0xaa, 0x93, 0xd5, 0xf2, 0xa8, 0xd5, 0xf2, 0x32, 0x2a, 0x06,
- 0xb1, 0x37, 0x4a, 0x6a, 0xc1, 0xe1, 0x20, 0xf6, 0xd4, 0x88, 0x00, 0x80, 0x37, 0xd1, 0x82, 0x2f,
- 0x58, 0x7a, 0x97, 0x74, 0x45, 0x20, 0xf9, 0x1e, 0x7d, 0x71, 0x38, 0x30, 0xce, 0x8f, 0x84, 0x5b,
- 0x99, 0x90, 0xce, 0x65, 0x44, 0x19, 0x53, 0xc2, 0x83, 0xf2, 0x38, 0x53, 0x9d, 0x8c, 0x2f, 0x73,
- 0x19, 0x91, 0xc4, 0x8b, 0xca, 0x31, 0x78, 0xf1, 0xf7, 0xbc, 0xb8, 0x86, 0xb7, 0x6d, 0x42, 0x9c,
- 0x09, 0x2f, 0x26, 0xc7, 0xe7, 0x13, 0x1e, 0x9f, 0xff, 0x5c, 0x81, 0xe3, 0xf3, 0x9d, 0xc8, 0xed,
- 0xb9, 0x21, 0xd4, 0x87, 0x26, 0x54, 0xfa, 0x82, 0xa8, 0xf4, 0x73, 0x0d, 0x2d, 0xdd, 0x30, 0xef,
- 0x77, 0x44, 0x69, 0x2d, 0x7c, 0x8d, 0x06, 0xb7, 0x48, 0xe0, 0x52, 0x47, 0xe4, 0x6b, 0x57, 0x93,
- 0x7c, 0x2d, 0xfb, 0x31, 0x1a, 0x63, 0xb5, 0x78, 0x02, 0x77, 0x69, 0x38, 0x30, 0x8c, 0xb1, 0x72,
- 0xc9, 0x8f, 0xf1, 0xdd, 0x9e, 0xf6, 0x73, 0x06, 0xfe, 0x99, 0x86, 0x96, 0x23, 0x1a, 0x99, 0xbd,
- 0xae, 0x1d, 0xf7, 0xe3, 0x9e, 0x09, 0x8b, 0x74, 0x1c, 0x9a, 0xbb, 0x2c, 0x83, 0x62, 0x11, 0x6f,
- 0x1d, 0x19, 0xf1, 0xdb, 0x4c, 0x6d, 0x3d, 0xd5, 0xba, 0xc3, 0x94, 0x78, 0xc0, 0xeb, 0xc3, 0x81,
- 0xb1, 0x12, 0x8d, 0x11, 0x4b, 0x6e, 0x2c, 0x8e, 0x93, 0xd7, 0xfe, 0xa0, 0xa1, 0xda, 0xd1, 0x5f,
- 0xf2, 0x78, 0x49, 0xd9, 0x0f, 0xe4, 0xa4, 0xac, 0xda, 0x6a, 0x34, 0x78, 0x11, 0xb7, 0x21, 0x17,
- 0x71, 0x1b, 0xfe, 0xc1, 0x2e, 0x0c, 0x2c, 0x29, 0xe2, 0x36, 0xde, 0x8a, 0x4d, 0x2f, 0x72, 0xa3,
- 0xc3, 0x27, 0x25, 0x71, 0xb5, 0xdf, 0x6b, 0xe8, 0xfc, 0x91, 0x43, 0x7f, 0x16, 0x3c, 0xac, 0xff,
- 0x27, 0x87, 0x96, 0xb7, 0xa8, 0xd5, 0x21, 0x7e, 0xe0, 0xd2, 0xc0, 0x8d, 0xdc, 0xf7, 0xbf, 0x06,
- 0xa9, 0xe6, 0x77, 0xd0, 0xb4, 0x47, 0xee, 0x75, 0xc5, 0x90, 0x0f, 0x61, 0xd1, 0xd2, 0xe0, 0xec,
- 0xb6, 0xe4, 0x91, 0x7b, 0xb7, 0x04, 0x2c, 0x69, 0x56, 0x25, 0x58, 0x4d, 0x54, 0x8b, 0xc7, 0x4d,
- 0x54, 0xeb, 0x9f, 0xe6, 0xa0, 0x70, 0x29, 0x45, 0xfa, 0xf4, 0xa7, 0x19, 0x5f, 0x49, 0xa0, 0xc5,
- 0xc9, 0x69, 0xdd, 0xf4, 0x6c, 0xd2, 0xeb, 0x4d, 0x4e, 0x4e, 0x9f, 0xcf, 0xc9, 0xe9, 0x63, 0xfe,
- 0x50, 0x45, 0x44, 0xf5, 0xf4, 0x53, 0xf7, 0x4b, 0x09, 0xea, 0x5f, 0xf3, 0x40, 0xd5, 0xdb, 0x24,
- 0xe8, 0xbb, 0x9e, 0x39, 0x39, 0x8f, 0x3e, 0xdb, 0x85, 0xdc, 0x2f, 0xe7, 0x08, 0x21, 0x51, 0xa8,
- 0x7c, 0x0c, 0x0a, 0x7d, 0x38, 0x8d, 0xa6, 0x81, 0x35, 0x37, 0x48, 0xc8, 0x52, 0x0b, 0x7c, 0x13,
- 0x55, 0xc2, 0xe4, 0x35, 0x19, 0xf0, 0xa7, 0xda, 0x5a, 0x4e, 0xf2, 0x32, 0xf5, 0x99, 0x19, 0x0f,
- 0x40, 0xda, 0x78, 0x64, 0xfc, 0x8d, 0x33, 0x9d, 0x91, 0x0d, 0xbc, 0x8e, 0x8a, 0xc0, 0x04, 0x47,
- 0xa4, 0x20, 0x67, 0x13, 0x6b, 0xd2, 0xab, 0x2c, 0xee, 0x24, 0x6f, 0xa6, 0xd8, 0x11, 0xaa, 0xcc,
- 0x48, 0x0f, 0xde, 0x35, 0x01, 0xe3, 0x24, 0x23, 0xd2, 0x6b, 0x27, 0x6e, 0x84, 0x37, 0x53, 0x8d,
- 0x70, 0x0c, 0xff, 0x08, 0xcd, 0xc2, 0xff, 0xba, 0x81, 0x78, 0xf8, 0x93, 0x32, 0x52, 0x36, 0xa6,
- 0xbc, 0x0a, 0x6a, 0x5f, 0x18, 0x0e, 0x8c, 0x73, 0x3d, 0x19, 0x57, 0x4c, 0xcf, 0x28, 0x22, 0xfc,
- 0x2e, 0xe2, 0x40, 0x97, 0xf0, 0x67, 0x24, 0xe2, 0xa1, 0xda, 0x79, 0xa5, 0x03, 0xf9, 0x89, 0x09,
- 0xff, 0xae, 0x3d, 0x09, 0x56, 0xcc, 0x4f, 0xcb, 0x12, 0xfc, 0x3a, 0x2a, 0xf9, 0xfc, 0xc1, 0x06,
- 0xf0, 0x37, 0xb9, 0xcb, 0xcc, 0xbc, 0xe3, 0x10, 0x0c, 0xe3, 0x88, 0x62, 0x2d, 0xd1, 0x66, 0x86,
- 0x02, 0x5e, 0xe7, 0x07, 0x2a, 0x4b, 0x86, 0xe4, 0xf2, 0x3f, 0x37, 0x24, 0x1a, 0xaa, 0x86, 0x04,
- 0x88, 0xfb, 0x08, 0xc7, 0x50, 0xb4, 0xea, 0x46, 0xb4, 0x1b, 0x8a, 0xb2, 0x15, 0xf0, 0xae, 0xda,
- 0xba, 0x98, 0x66, 0xf3, 0xe3, 0xca, 0x5a, 0xbc, 0x24, 0x17, 0x67, 0x44, 0x4a, 0x2f, 0xf3, 0x59,
- 0x29, 0x63, 0xc1, 0x0e, 0x5c, 0x9e, 0xc3, 0x5c, 0x92, 0x58, 0x20, 0x5d, 0xa9, 0x73, 0x16, 0xf0,
- 0x66, 0x2a, 0x0b, 0x38, 0xc6, 0x09, 0x2e, 0xee, 0x69, 0x60, 0x72, 0x29, 0x04, 0x97, 0x2f, 0x70,
- 0x12, 0x82, 0x0b, 0x2c, 0x4b, 0x70, 0x01, 0xe3, 0x2e, 0x9a, 0x09, 0xe4, 0xac, 0x0c, 0x0e, 0x46,
- 0x12, 0xab, 0x1e, 0x4f, 0xd9, 0x38, 0xab, 0x14, 0x25, 0x95, 0x55, 0x8a, 0x08, 0x6f, 0x23, 0x64,
- 0xa7, 0xd9, 0x08, 0xdc, 0x36, 0x57, 0x5b, 0xe7, 0x12, 0xeb, 0x99, 0x3c, 0xa5, 0xad, 0x0f, 0x07,
- 0xc6, 0xe2, 0xa8, 0xb9, 0x62, 0x57, 0x32, 0xc3, 0xc2, 0x60, 0x27, 0x9b, 0x31, 0xdc, 0xcb, 0x4b,
- 0x61, 0x50, 0x77, 0x69, 0xb1, 0xc2, 0x26, 0x98, 0x1a, 0x86, 0x14, 0xc6, 0x6f, 0xa3, 0x6a, 0x3c,
- 0x3a, 0xb7, 0xe9, 0x73, 0x60, 0x52, 0x3f, 0xea, 0x48, 0xc7, 0xb3, 0x38, 0x49, 0x41, 0x31, 0x2b,
- 0x5b, 0xc2, 0xef, 0xa0, 0xe9, 0xa4, 0x0e, 0xec, 0x7a, 0x3b, 0x54, 0x5f, 0x50, 0x2d, 0x67, 0x4b,
- 0xc0, 0xdc, 0xb2, 0x3b, 0x42, 0x55, 0xcb, 0x92, 0x00, 0xdb, 0x68, 0x36, 0x50, 0x4e, 0x2e, 0x3a,
- 0x06, 0xdb, 0x17, 0xc6, 0x7c, 0xba, 0x34, 0xc0, 0xcf, 0x0d, 0x07, 0x86, 0xae, 0xaa, 0x29, 0x3d,
- 0x64, 0x4c, 0xb2, 0x40, 0xfb, 0xc9, 0x7d, 0xb1, 0xbe, 0xa4, 0x06, 0x5a, 0xbd, 0x48, 0x16, 0x3b,
- 0x4a, 0x82, 0xa9, 0x81, 0x4e, 0x61, 0x46, 0x07, 0x3f, 0xbd, 0xd6, 0xd7, 0x97, 0x55, 0x3a, 0x64,
- 0x2e, 0xfc, 0x39, 0x1d, 0x46, 0xcd, 0x55, 0x3a, 0x8c, 0xf0, 0x76, 0x19, 0x15, 0xe1, 0x69, 0x74,
- 0x58, 0xff, 0x49, 0x0e, 0xcd, 0x65, 0xca, 0x23, 0xf8, 0x1b, 0x28, 0x0f, 0x5b, 0x18, 0xcf, 0x27,
- 0xf0, 0x70, 0x60, 0xcc, 0x7a, 0xea, 0xfe, 0x05, 0x72, 0xdc, 0x42, 0xe5, 0xa4, 0x4c, 0x25, 0xea,
- 0x14, 0x90, 0x4b, 0x24, 0x98, 0x9c, 0x4b, 0x24, 0x18, 0x6e, 0xa2, 0x52, 0x9f, 0xef, 0x3d, 0x22,
- 0x9b, 0x80, 0x65, 0x47, 0x40, 0xf2, 0x0e, 0x29, 0x20, 0x69, 0x83, 0xcb, 0x1f, 0xa3, 0x14, 0x97,
- 0x56, 0x69, 0x0a, 0x4f, 0x53, 0xa5, 0xa9, 0xbf, 0x8f, 0x30, 0x04, 0x70, 0x3b, 0x0a, 0x88, 0xd9,
- 0x4f, 0x36, 0xc7, 0x55, 0x94, 0x4b, 0xb3, 0xaa, 0xf9, 0xe1, 0xc0, 0x98, 0x76, 0xe5, 0x94, 0x21,
- 0xe7, 0x3a, 0xb8, 0x3d, 0x1a, 0x0d, 0xdf, 0xee, 0x16, 0xa0, 0x43, 0x79, 0x8b, 0x7d, 0xd2, 0x00,
- 0xeb, 0xbf, 0xca, 0xa1, 0x99, 0x2d, 0x48, 0xb5, 0x3a, 0x3c, 0x31, 0x3c, 0x46, 0xbf, 0xcf, 0xa3,
- 0xc2, 0x3d, 0x33, 0xb2, 0xf7, 0xa0, 0xd7, 0x32, 0x1f, 0x1a, 0x00, 0xf2, 0xd0, 0x00, 0xc0, 0xeb,
- 0x68, 0x6e, 0x27, 0xa0, 0xfd, 0xae, 0xe8, 0x8e, 0xa5, 0x43, 0x3c, 0xf0, 0xb0, 0x2a, 0x31, 0x91,
- 0x70, 0x54, 0xc9, 0x87, 0x66, 0x14, 0xc1, 0x28, 0x03, 0xcc, 0x3f, 0x31, 0x03, 0x7c, 0x15, 0xcd,
- 0x92, 0x20, 0xa0, 0xc1, 0xe6, 0xce, 0x0d, 0x37, 0x0c, 0x19, 0x67, 0x0b, 0xe0, 0x23, 0x4c, 0x24,
- 0x55, 0x22, 0x29, 0x67, 0x74, 0xea, 0xbf, 0xd3, 0xd0, 0xf4, 0xdb, 0xcc, 0xff, 0x24, 0x26, 0xa9,
- 0x07, 0xda, 0x13, 0x3d, 0x38, 0x59, 0x92, 0x7b, 0x05, 0x95, 0x20, 0x4e, 0x69, 0x7c, 0xf8, 0xce,
- 0x12, 0xd0, 0xbe, 0xa2, 0x50, 0xe4, 0xc8, 0xe5, 0x37, 0x51, 0x01, 0x68, 0x85, 0x2b, 0xa8, 0xb0,
- 0xc1, 0x7c, 0x9f, 0x3f, 0x83, 0xab, 0xa8, 0xb4, 0x71, 0xd7, 0xb5, 0x23, 0xe2, 0xcc, 0x6b, 0xb8,
- 0x84, 0xa6, 0x6e, 0xde, 0xbc, 0x31, 0x9f, 0xc3, 0x8b, 0x68, 0xfe, 0x55, 0x62, 0x3a, 0x3d, 0xd7,
- 0x23, 0x1b, 0xf7, 0xf9, 0x26, 0x32, 0x3f, 0x85, 0xa7, 0x51, 0xb9, 0x43, 0xf6, 0x09, 0x34, 0xce,
- 0xb7, 0x3e, 0xd5, 0x50, 0x81, 0x67, 0xf3, 0x04, 0xcd, 0xbd, 0x4e, 0x22, 0xce, 0x07, 0x40, 0x42,
- 0x8c, 0xd3, 0xfd, 0x2a, 0xa5, 0x48, 0xed, 0xdc, 0x88, 0x67, 0x0a, 0x67, 0xeb, 0x97, 0x7e, 0xfc,
- 0xc9, 0xbf, 0x7f, 0x9d, 0xbb, 0x58, 0xd7, 0x9b, 0x77, 0xbf, 0xd5, 0xdc, 0xa7, 0xd6, 0x95, 0x90,
- 0x44, 0xcd, 0x07, 0x10, 0x98, 0x0f, 0x9a, 0x0f, 0x5c, 0xe7, 0x83, 0x6b, 0xda, 0xe5, 0x17, 0x35,
- 0x7c, 0x0d, 0x15, 0x20, 0xbc, 0x98, 0x13, 0x56, 0x0e, 0xf5, 0xd1, 0xb6, 0xa7, 0x7e, 0x9a, 0xd3,
- 0x40, 0xb7, 0xf8, 0x06, 0xfc, 0x0c, 0x02, 0x2f, 0x3f, 0x96, 0xdc, 0x6f, 0xb0, 0x20, 0xd5, 0xf8,
- 0x6a, 0xcd, 0x1b, 0xad, 0xef, 0x11, 0xfb, 0xa0, 0x43, 0x42, 0x9f, 0x7a, 0x21, 0x69, 0xbf, 0xf3,
- 0x8f, 0x87, 0x2b, 0xda, 0x47, 0x0f, 0x57, 0xb4, 0x7f, 0x3d, 0x5c, 0xd1, 0x7e, 0xf1, 0x68, 0xe5,
- 0xcc, 0x47, 0x8f, 0x56, 0xce, 0xfc, 0xf3, 0xd1, 0xca, 0x99, 0x1f, 0x7e, 0x73, 0xd7, 0x8d, 0xf6,
- 0x62, 0xab, 0x61, 0xd3, 0x7e, 0xd3, 0x0c, 0xfa, 0xa6, 0x63, 0xfa, 0x01, 0x65, 0x01, 0x12, 0x7f,
- 0x25, 0xbf, 0x8e, 0xf8, 0x53, 0x6e, 0xf1, 0x3a, 0x00, 0xb7, 0xb8, 0xb8, 0xb1, 0x49, 0x1b, 0xd7,
- 0x7d, 0xd7, 0x2a, 0x82, 0x0f, 0x57, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x55, 0x79, 0x72, 0x3b,
- 0xfc, 0x31, 0x00, 0x00,
+ 0x46, 0x4c, 0xa6, 0x72, 0x52, 0x04, 0x46, 0x81, 0xc2, 0x52, 0x94, 0x44, 0x6a, 0x5c, 0x3b, 0x94,
+ 0x8d, 0xa4, 0x45, 0x00, 0x76, 0x3f, 0x46, 0xd4, 0x4a, 0xe4, 0xce, 0x66, 0x3f, 0x64, 0x2b, 0x46,
+ 0x2e, 0xed, 0xa5, 0x87, 0xa2, 0xe9, 0x07, 0x7a, 0x2b, 0xda, 0xa2, 0xc7, 0x1e, 0xfb, 0x17, 0xf4,
+ 0x50, 0x14, 0x3d, 0x06, 0xc9, 0xa5, 0x27, 0xa2, 0xb5, 0x8b, 0x14, 0xe0, 0xa9, 0xf7, 0x5e, 0x8a,
+ 0x79, 0x33, 0xbb, 0x9c, 0x59, 0x53, 0x90, 0xac, 0x7c, 0x19, 0x0a, 0x4f, 0xb6, 0x7e, 0x6f, 0xde,
+ 0x9b, 0x37, 0x6f, 0x7e, 0x33, 0xf3, 0x66, 0xdf, 0x10, 0x9d, 0xf7, 0xf7, 0x3b, 0x4d, 0xd3, 0x77,
+ 0x9b, 0xe4, 0x80, 0x78, 0x51, 0xc3, 0x0f, 0x68, 0x44, 0xf1, 0x84, 0xe9, 0xbb, 0x35, 0xa3, 0x43,
+ 0x69, 0xa7, 0x4b, 0x9a, 0x00, 0x59, 0xf1, 0x4e, 0x33, 0x72, 0x7b, 0x24, 0x8c, 0xcc, 0x9e, 0xcf,
+ 0x5b, 0xd5, 0xe6, 0x13, 0xd5, 0x30, 0xb6, 0x7a, 0x6e, 0x94, 0x45, 0x77, 0x89, 0xd9, 0x8d, 0x76,
+ 0x05, 0x7a, 0x29, 0x6b, 0x8c, 0xf4, 0xfc, 0xe8, 0x50, 0x08, 0x9f, 0x13, 0x42, 0xa6, 0x65, 0x7a,
+ 0x1e, 0x8d, 0xcc, 0xc8, 0xa5, 0x5e, 0x28, 0xa4, 0x2f, 0xed, 0xbf, 0x12, 0x36, 0x5c, 0xca, 0xa4,
+ 0x3d, 0xd3, 0xde, 0x75, 0x3d, 0x12, 0x1c, 0x36, 0x93, 0x4e, 0x02, 0x12, 0xd2, 0x38, 0xb0, 0x49,
+ 0xb3, 0x43, 0x3c, 0x12, 0x98, 0x11, 0x71, 0xb8, 0x56, 0xfd, 0xb7, 0x39, 0x34, 0xb7, 0x45, 0xad,
+ 0x6d, 0x70, 0x2d, 0x22, 0xce, 0x06, 0x1b, 0x1e, 0xbe, 0x8a, 0x8a, 0x7b, 0xd4, 0x6a, 0xbb, 0x8e,
+ 0xae, 0x2d, 0x6b, 0x2b, 0x95, 0xb5, 0xf3, 0x83, 0xbe, 0x31, 0xb3, 0x47, 0xad, 0x4d, 0xe7, 0x05,
+ 0xda, 0x73, 0x23, 0x70, 0xaa, 0x55, 0x00, 0x00, 0xbf, 0x84, 0x10, 0x6b, 0x1b, 0x92, 0x88, 0xb5,
+ 0xcf, 0x41, 0xfb, 0xc5, 0x41, 0xdf, 0xc0, 0x7b, 0xd4, 0xda, 0x26, 0x91, 0xa2, 0x52, 0x4e, 0x30,
+ 0xfc, 0x3c, 0x2a, 0xbc, 0x17, 0x93, 0x98, 0xe8, 0x13, 0xc3, 0x0e, 0x00, 0x90, 0x3b, 0x00, 0x00,
+ 0x7f, 0x0f, 0x95, 0xec, 0x80, 0x30, 0x9f, 0xf5, 0xfc, 0xb2, 0xb6, 0x52, 0x5d, 0xad, 0x35, 0x78,
+ 0x20, 0x1a, 0x49, 0x94, 0x1a, 0x77, 0x93, 0x90, 0xaf, 0x2d, 0x0c, 0xfa, 0xc6, 0x9c, 0x68, 0x2e,
+ 0x99, 0x4a, 0x2c, 0xe0, 0x6b, 0x68, 0x62, 0x8f, 0x5a, 0x7a, 0x01, 0x0c, 0x95, 0x1b, 0xa6, 0xef,
+ 0x36, 0xb6, 0xa8, 0xb5, 0x36, 0x37, 0xe8, 0x1b, 0x53, 0x7b, 0xd4, 0x92, 0x54, 0x58, 0xbb, 0xfa,
+ 0x40, 0x43, 0xd3, 0x5b, 0xd4, 0x7a, 0x8b, 0x39, 0x72, 0xd6, 0x63, 0x53, 0xff, 0x63, 0x0e, 0x06,
+ 0xfb, 0x26, 0x31, 0xc3, 0xb3, 0x4f, 0x84, 0x6f, 0x23, 0x64, 0x77, 0xe3, 0x30, 0x22, 0x01, 0xf3,
+ 0xb6, 0x00, 0x9d, 0x5f, 0x18, 0xf4, 0x8d, 0xf3, 0x02, 0x55, 0xdc, 0xad, 0xa4, 0x60, 0xfd, 0x97,
+ 0x79, 0xb4, 0x90, 0x04, 0xa9, 0x45, 0xa2, 0x38, 0xf0, 0xc6, 0xb1, 0x3a, 0x22, 0x56, 0xf8, 0x05,
+ 0x54, 0x0c, 0x88, 0x19, 0x52, 0x4f, 0x2f, 0x82, 0xce, 0xfc, 0xa0, 0x6f, 0xcc, 0x72, 0x44, 0x52,
+ 0x10, 0x6d, 0xf0, 0x77, 0xd1, 0xd4, 0x7e, 0x6c, 0x91, 0xc0, 0x23, 0x11, 0x09, 0x59, 0x47, 0x25,
+ 0x50, 0xaa, 0x0d, 0xfa, 0xc6, 0xe2, 0x50, 0xa0, 0xf4, 0x35, 0x29, 0xe3, 0xcc, 0x4d, 0x9f, 0x3a,
+ 0x6d, 0x2f, 0xee, 0x59, 0x24, 0xd0, 0xcb, 0xcb, 0xda, 0x4a, 0x81, 0xbb, 0xe9, 0x53, 0xe7, 0xfb,
+ 0x00, 0xca, 0x6e, 0xa6, 0x20, 0xeb, 0x38, 0x88, 0xbd, 0xb6, 0x19, 0x81, 0x88, 0x38, 0x7a, 0x65,
+ 0x59, 0x5b, 0x29, 0xf3, 0x8e, 0x83, 0xd8, 0xbb, 0x99, 0xe0, 0x72, 0xc7, 0x32, 0x5e, 0xff, 0xaf,
+ 0x86, 0xe6, 0x13, 0x4e, 0x6c, 0x3c, 0xf0, 0xdd, 0xe0, 0xec, 0xef, 0x15, 0x1f, 0xe6, 0xd1, 0xcc,
+ 0x16, 0xb5, 0xee, 0x10, 0xcf, 0x71, 0xbd, 0xce, 0x78, 0x01, 0x8c, 0x5e, 0x00, 0x4f, 0x50, 0xba,
+ 0xf8, 0x99, 0x28, 0x5d, 0x3a, 0x31, 0xa5, 0x5f, 0x44, 0x65, 0xd0, 0x33, 0x7b, 0x04, 0x16, 0x42,
+ 0x85, 0x0f, 0x91, 0x35, 0x30, 0x7b, 0x72, 0xb4, 0x4a, 0x02, 0x62, 0xae, 0x26, 0x1a, 0xa1, 0x6f,
+ 0xda, 0x04, 0x16, 0x81, 0x70, 0x55, 0xb4, 0x01, 0x5c, 0x76, 0x55, 0xc6, 0xeb, 0x7f, 0xe5, 0x8c,
+ 0x68, 0xc5, 0x9e, 0x37, 0x66, 0xc4, 0x17, 0xc7, 0x88, 0xeb, 0xa8, 0xe2, 0x51, 0x87, 0xf0, 0xa9,
+ 0x2d, 0x0d, 0xa3, 0xc4, 0xc0, 0xcc, 0xdc, 0x96, 0x13, 0xec, 0xd4, 0x3b, 0xa3, 0x4c, 0xa3, 0xca,
+ 0xe9, 0x68, 0x84, 0x9e, 0x92, 0x46, 0x7f, 0x2e, 0xa2, 0xf3, 0x5b, 0xd4, 0xda, 0xf4, 0x3a, 0x01,
+ 0x09, 0xc3, 0x4d, 0x6f, 0x87, 0x8e, 0xa9, 0x74, 0xd6, 0xa8, 0x84, 0x4e, 0x47, 0xa5, 0xea, 0xd3,
+ 0x51, 0x09, 0x3f, 0x44, 0x73, 0x2e, 0xa7, 0x51, 0xdb, 0x74, 0x1c, 0xf6, 0x2f, 0x09, 0xf5, 0xca,
+ 0xf2, 0xc4, 0x4a, 0x75, 0xb5, 0x91, 0x64, 0xfe, 0x59, 0x9e, 0x35, 0x04, 0x70, 0x33, 0x51, 0xd8,
+ 0xf0, 0xa2, 0xe0, 0x70, 0x6d, 0x69, 0xd0, 0x37, 0x6a, 0x6e, 0x46, 0x24, 0x75, 0x3c, 0x9b, 0x95,
+ 0xd5, 0xf6, 0xd1, 0xc2, 0x48, 0x53, 0xf8, 0x0a, 0x9a, 0xd8, 0x27, 0x87, 0xc0, 0xe2, 0x02, 0xbf,
+ 0x77, 0xec, 0x93, 0x43, 0xf9, 0xde, 0xb1, 0x4f, 0x0e, 0x19, 0x17, 0x0f, 0xcc, 0x6e, 0x4c, 0x04,
+ 0x79, 0x81, 0x8b, 0x00, 0xc8, 0x5c, 0x04, 0xe0, 0x46, 0xee, 0x15, 0xad, 0xfe, 0xbf, 0x3c, 0xd2,
+ 0xb7, 0xa8, 0x75, 0xcf, 0x33, 0xad, 0x2e, 0xb9, 0x4b, 0xb7, 0xed, 0x5d, 0xe2, 0xc4, 0x5d, 0x32,
+ 0x5e, 0x39, 0xcf, 0x44, 0x5e, 0xaa, 0xac, 0xb3, 0xf2, 0xa9, 0xd6, 0x59, 0xe5, 0x19, 0x5e, 0x67,
+ 0xf5, 0x8f, 0x4b, 0x70, 0x6f, 0x7c, 0xcd, 0x74, 0xbb, 0xe3, 0xbb, 0xd0, 0xe7, 0xc3, 0xb9, 0x77,
+ 0x11, 0x22, 0x0f, 0xdc, 0xa8, 0x6d, 0x53, 0x87, 0x84, 0x7a, 0x09, 0xf6, 0xac, 0x7a, 0xb2, 0x67,
+ 0x49, 0x81, 0x6e, 0x6c, 0x3c, 0x70, 0xa3, 0x75, 0xd6, 0x88, 0xef, 0x53, 0x17, 0x99, 0x27, 0x24,
+ 0xc1, 0x86, 0x86, 0x75, 0xad, 0x55, 0x49, 0xe1, 0x27, 0x19, 0x5d, 0xfe, 0x2c, 0x8c, 0xae, 0x9c,
+ 0x8a, 0xd1, 0xe8, 0x54, 0x8c, 0x9e, 0x3a, 0x1d, 0xa3, 0xa7, 0x9f, 0xf2, 0xe4, 0x70, 0x10, 0xb6,
+ 0xa9, 0x17, 0x99, 0xae, 0x47, 0x82, 0x76, 0x18, 0x99, 0x51, 0xcc, 0x8e, 0x8e, 0x2a, 0x4c, 0xc3,
+ 0x3c, 0x4c, 0xc3, 0x7a, 0x22, 0xde, 0x06, 0xe9, 0x9a, 0x31, 0xe8, 0x1b, 0x97, 0x6c, 0x15, 0x54,
+ 0x4e, 0x88, 0xb9, 0x27, 0x84, 0xf8, 0x65, 0x54, 0xb0, 0xcd, 0x38, 0x24, 0xfa, 0xe4, 0xb2, 0xb6,
+ 0x32, 0xbd, 0x8a, 0xb8, 0x61, 0x86, 0x70, 0x3a, 0x83, 0x50, 0xa6, 0x33, 0x00, 0x35, 0x07, 0x4d,
+ 0xab, 0xb3, 0x2e, 0x1f, 0x29, 0x95, 0x93, 0x1d, 0x29, 0x85, 0x63, 0x8f, 0x94, 0x4f, 0x72, 0x08,
+ 0xb3, 0x0b, 0x5e, 0x40, 0x98, 0xe8, 0x6b, 0x90, 0xd1, 0xbf, 0x8c, 0x2a, 0x01, 0x79, 0x2f, 0x26,
+ 0x61, 0x44, 0x03, 0x79, 0x5d, 0xa7, 0xa0, 0xcc, 0xce, 0x14, 0x7c, 0xba, 0x75, 0x5d, 0xff, 0x4d,
+ 0x1e, 0x3e, 0xb7, 0x8a, 0xa8, 0x8e, 0x77, 0xcb, 0xa3, 0x76, 0xcb, 0xab, 0xa8, 0x18, 0xc4, 0xde,
+ 0x30, 0xa9, 0x05, 0x87, 0x83, 0xd8, 0x53, 0x23, 0x02, 0x00, 0xde, 0x44, 0x73, 0xbe, 0x60, 0xe9,
+ 0x01, 0x69, 0x8b, 0x40, 0xf2, 0x33, 0xfa, 0xf2, 0xa0, 0x6f, 0x5c, 0x1c, 0x0a, 0xb7, 0x32, 0x21,
+ 0x9d, 0xc9, 0x88, 0x32, 0xa6, 0x84, 0x07, 0xe5, 0x51, 0xa6, 0x5a, 0x19, 0x5f, 0x66, 0x32, 0x22,
+ 0x89, 0x17, 0x95, 0x13, 0xf0, 0xe2, 0x6f, 0x79, 0xf1, 0x19, 0xde, 0xb6, 0x09, 0x71, 0xc6, 0xbc,
+ 0x18, 0x5f, 0x9f, 0x4f, 0x79, 0x7d, 0xfe, 0x57, 0x15, 0xae, 0xcf, 0xf7, 0x22, 0xb7, 0xeb, 0x86,
+ 0x50, 0x1f, 0x1a, 0x53, 0xe9, 0x0b, 0xa2, 0xd2, 0xcf, 0x35, 0xb4, 0x70, 0xcb, 0x7c, 0xd0, 0x12,
+ 0xa5, 0xb5, 0xf0, 0x35, 0x1a, 0xdc, 0x21, 0x81, 0x4b, 0x1d, 0x91, 0xaf, 0x5d, 0x4f, 0xf2, 0xb5,
+ 0xec, 0x64, 0x34, 0x46, 0x6a, 0xf1, 0x04, 0xee, 0xca, 0xa0, 0x6f, 0x18, 0x23, 0xe5, 0x92, 0x1f,
+ 0xa3, 0xbb, 0x3d, 0xeb, 0xf7, 0x0c, 0xfc, 0x33, 0x0d, 0x2d, 0x46, 0x34, 0x32, 0xbb, 0x6d, 0x3b,
+ 0xee, 0xc5, 0x5d, 0x13, 0x36, 0xe9, 0x38, 0x34, 0x3b, 0x2c, 0x83, 0x62, 0x11, 0x5f, 0x3d, 0x32,
+ 0xe2, 0x77, 0x99, 0xda, 0x7a, 0xaa, 0x75, 0x8f, 0x29, 0xf1, 0x80, 0xd7, 0x07, 0x7d, 0x63, 0x29,
+ 0x1a, 0x21, 0x96, 0xdc, 0x98, 0x1f, 0x25, 0x87, 0xf9, 0xbf, 0x79, 0xd0, 0x19, 0x31, 0xff, 0x53,
+ 0xc7, 0xcc, 0xff, 0x48, 0x2d, 0x69, 0xfe, 0x47, 0xca, 0xe5, 0xf9, 0x1f, 0xd9, 0xa0, 0xf6, 0x07,
+ 0x0d, 0xd5, 0x8e, 0xa6, 0xd6, 0xc9, 0xb2, 0xc4, 0x1f, 0xc8, 0x59, 0x62, 0x75, 0xb5, 0xd1, 0xe0,
+ 0x55, 0xe5, 0x86, 0x5c, 0x55, 0x6e, 0xf8, 0xfb, 0x1d, 0x18, 0x5b, 0x52, 0x55, 0x6e, 0xbc, 0x15,
+ 0x9b, 0x5e, 0xe4, 0x46, 0x87, 0xc7, 0x65, 0x95, 0xb5, 0xdf, 0x6b, 0xe8, 0xe2, 0x91, 0x73, 0xf1,
+ 0x4c, 0x78, 0xc8, 0x82, 0x78, 0xf4, 0xfc, 0x3c, 0x0b, 0x2e, 0xd6, 0xff, 0x93, 0x43, 0x8b, 0x5b,
+ 0xd4, 0x6a, 0x11, 0x3f, 0x70, 0x69, 0xe0, 0x46, 0xee, 0xfb, 0x5f, 0x83, 0xf4, 0xfc, 0x3b, 0x68,
+ 0xd2, 0x23, 0xf7, 0xdb, 0x62, 0xc8, 0x87, 0xb0, 0xd1, 0x6b, 0x70, 0xdf, 0x5d, 0xf0, 0xc8, 0xfd,
+ 0x3b, 0x02, 0x96, 0x34, 0xab, 0x12, 0xac, 0x26, 0xf7, 0xc5, 0x93, 0x26, 0xf7, 0xf5, 0x4f, 0x73,
+ 0x50, 0xec, 0x95, 0x22, 0x7d, 0xf6, 0x53, 0xb3, 0xaf, 0x24, 0xd0, 0xe2, 0xb6, 0xb9, 0x6e, 0x7a,
+ 0x36, 0xe9, 0x76, 0xc7, 0xb7, 0xcd, 0xcf, 0xe7, 0xb6, 0xf9, 0x31, 0x7f, 0xdc, 0x23, 0xa2, 0x7a,
+ 0xf6, 0xa9, 0xfb, 0xa5, 0x04, 0xf5, 0x2f, 0x79, 0xa0, 0xea, 0x5d, 0x12, 0xf4, 0x5c, 0xcf, 0x1c,
+ 0xdf, 0xe1, 0x9f, 0xed, 0xe2, 0xf7, 0x97, 0x73, 0xed, 0x92, 0x28, 0x54, 0x3e, 0x01, 0x85, 0x3e,
+ 0x9c, 0x44, 0x93, 0xc0, 0x9a, 0x5b, 0x24, 0x84, 0x54, 0xf2, 0x36, 0xaa, 0x84, 0xc9, 0x0b, 0x3c,
+ 0xe0, 0x4f, 0x75, 0x75, 0x31, 0xc9, 0x1e, 0xd5, 0xa7, 0x79, 0x3c, 0x00, 0x69, 0xe3, 0xa1, 0xf1,
+ 0x37, 0xce, 0xb5, 0x86, 0x36, 0xf0, 0x3a, 0x2a, 0x02, 0x13, 0x1c, 0x91, 0x82, 0x9c, 0x4f, 0xac,
+ 0x49, 0x2f, 0xd9, 0xb8, 0x93, 0xbc, 0x99, 0x62, 0x47, 0xa8, 0x32, 0x23, 0x5d, 0x78, 0x0b, 0x06,
+ 0x8c, 0x93, 0x8c, 0x48, 0x2f, 0xc4, 0xb8, 0x11, 0xde, 0x4c, 0x35, 0xc2, 0x31, 0xfc, 0x23, 0x34,
+ 0x0d, 0xff, 0x6b, 0x07, 0xe2, 0xb1, 0x54, 0xca, 0x48, 0xd9, 0x98, 0xf2, 0x92, 0x6a, 0xed, 0xd2,
+ 0xa0, 0x6f, 0x5c, 0xe8, 0xca, 0xb8, 0x62, 0x7a, 0x4a, 0x11, 0xe1, 0x77, 0x11, 0x07, 0xda, 0x84,
+ 0x3f, 0xbd, 0x11, 0x8f, 0xfb, 0x2e, 0x2a, 0x1d, 0xc8, 0xcf, 0x72, 0xf8, 0xbc, 0x76, 0x25, 0x58,
+ 0x31, 0x3f, 0x29, 0x4b, 0xf0, 0xeb, 0xa8, 0xe4, 0xf3, 0x47, 0x2e, 0xc0, 0xdf, 0xe4, 0xfb, 0x6f,
+ 0xe6, 0xed, 0x8b, 0x60, 0x18, 0x47, 0x14, 0x6b, 0x89, 0x36, 0x33, 0x14, 0xf0, 0xb7, 0x11, 0x40,
+ 0x65, 0xc9, 0x90, 0xfc, 0x64, 0x82, 0x1b, 0x12, 0x0d, 0x55, 0x43, 0x02, 0xc4, 0x3d, 0x84, 0x63,
+ 0x28, 0xf4, 0xb5, 0x23, 0xda, 0x0e, 0x45, 0xa9, 0x0f, 0x78, 0x57, 0x5d, 0xbd, 0x9c, 0xde, 0x39,
+ 0x46, 0x95, 0x02, 0x79, 0x19, 0x33, 0xce, 0x88, 0x94, 0x5e, 0x66, 0xb3, 0x52, 0xc6, 0x82, 0x1d,
+ 0x28, 0x38, 0xc0, 0x5a, 0x92, 0x58, 0x20, 0x95, 0x21, 0x38, 0x0b, 0x78, 0x33, 0x95, 0x05, 0x1c,
+ 0xe3, 0x04, 0x17, 0xdf, 0xb6, 0x60, 0x71, 0x29, 0x04, 0x97, 0x3f, 0x7a, 0x25, 0x04, 0x17, 0x58,
+ 0x96, 0xe0, 0x02, 0xc6, 0x6d, 0x34, 0x15, 0xc8, 0x59, 0x19, 0x5c, 0x26, 0x25, 0x56, 0x3d, 0x99,
+ 0xb2, 0x71, 0x56, 0x29, 0x4a, 0x2a, 0xab, 0x14, 0x11, 0xde, 0x46, 0xc8, 0x4e, 0xb3, 0x11, 0xf8,
+ 0x42, 0x5f, 0x5d, 0xbd, 0x90, 0x58, 0xcf, 0xe4, 0x29, 0x6b, 0xfa, 0xa0, 0x6f, 0xcc, 0x0f, 0x9b,
+ 0x2b, 0x76, 0x25, 0x33, 0x2c, 0x0c, 0x76, 0x72, 0x18, 0x43, 0x2d, 0x43, 0x0a, 0x83, 0x7a, 0x4a,
+ 0x8b, 0x1d, 0x36, 0xc1, 0xd4, 0x30, 0xa4, 0x30, 0x7e, 0x1b, 0x55, 0xe3, 0xe1, 0xed, 0x52, 0x9f,
+ 0x01, 0x93, 0xfa, 0x51, 0x17, 0x4f, 0x9e, 0xc5, 0x49, 0x0a, 0x8a, 0x59, 0xd9, 0x12, 0x7e, 0x07,
+ 0x4d, 0x26, 0xb5, 0x73, 0xd7, 0xdb, 0xa1, 0xfa, 0x9c, 0x6a, 0x39, 0x5b, 0x36, 0xe7, 0x96, 0xdd,
+ 0x21, 0xaa, 0x5a, 0x96, 0x04, 0xd8, 0x46, 0xd3, 0x81, 0x72, 0x73, 0xd1, 0x31, 0xd8, 0xbe, 0x34,
+ 0x62, 0xea, 0xd2, 0x00, 0x3f, 0x37, 0xe8, 0x1b, 0xba, 0xaa, 0xa6, 0xf4, 0x90, 0x31, 0xc9, 0x02,
+ 0xed, 0x27, 0xdf, 0xd8, 0xf5, 0x05, 0x35, 0xd0, 0xea, 0xc7, 0x77, 0x71, 0xa2, 0x24, 0x98, 0x1a,
+ 0xe8, 0x14, 0x66, 0x74, 0xf0, 0xd3, 0x52, 0x88, 0xbe, 0xa8, 0xd2, 0x21, 0x53, 0x24, 0xe1, 0x74,
+ 0x18, 0x36, 0x57, 0xe9, 0x30, 0xc4, 0xd7, 0xca, 0xa8, 0x08, 0xcf, 0xc9, 0xc3, 0xfa, 0x4f, 0x72,
+ 0x68, 0x26, 0x53, 0x52, 0xc2, 0xdf, 0x40, 0x79, 0x38, 0xc2, 0x78, 0x3e, 0x81, 0x07, 0x7d, 0x63,
+ 0xda, 0x53, 0xcf, 0x2f, 0x90, 0xe3, 0x55, 0x54, 0x4e, 0x4a, 0x7b, 0xa2, 0xb6, 0x03, 0xb9, 0x44,
+ 0x82, 0xc9, 0xb9, 0x44, 0x82, 0xe1, 0x26, 0x2a, 0xf5, 0xf8, 0xd9, 0x23, 0xb2, 0x09, 0xd8, 0x76,
+ 0x04, 0x24, 0x9f, 0x90, 0x02, 0x92, 0x0e, 0xb8, 0xfc, 0x09, 0xca, 0x97, 0x69, 0x65, 0xab, 0xf0,
+ 0x34, 0x95, 0xad, 0xfa, 0xfb, 0x08, 0x43, 0x00, 0xb7, 0xa3, 0x80, 0x98, 0xbd, 0xe4, 0x70, 0x5c,
+ 0x46, 0xb9, 0x34, 0xab, 0x9a, 0x1d, 0xf4, 0x8d, 0x49, 0x57, 0x4e, 0x19, 0x72, 0xae, 0x83, 0xd7,
+ 0x86, 0xa3, 0xe1, 0xc7, 0xdd, 0x1c, 0x74, 0x28, 0x1f, 0xb1, 0xc7, 0x0d, 0xb0, 0xfe, 0xab, 0x1c,
+ 0x9a, 0xda, 0x82, 0x54, 0xab, 0xc5, 0x13, 0xc3, 0x13, 0xf4, 0xfb, 0x3c, 0x2a, 0xdc, 0x37, 0x23,
+ 0x7b, 0x17, 0x7a, 0x2d, 0xf3, 0xa1, 0x01, 0x20, 0x0f, 0x0d, 0x00, 0xbc, 0x8e, 0x66, 0x76, 0x02,
+ 0xda, 0x6b, 0x8b, 0xee, 0x58, 0x3a, 0xc4, 0x03, 0x0f, 0xbb, 0x12, 0x13, 0x09, 0x47, 0x95, 0x7c,
+ 0x68, 0x4a, 0x11, 0x0c, 0x33, 0xc0, 0xfc, 0xb1, 0x19, 0xe0, 0xab, 0x68, 0x9a, 0x04, 0x01, 0x0d,
+ 0x36, 0x77, 0x6e, 0xb9, 0x61, 0xc8, 0x38, 0x5b, 0x00, 0x1f, 0x61, 0x21, 0xa9, 0x12, 0x49, 0x39,
+ 0xa3, 0x53, 0xff, 0x9d, 0x86, 0x26, 0xdf, 0x66, 0xfe, 0x27, 0x31, 0x49, 0x3d, 0xd0, 0x8e, 0xf5,
+ 0xe0, 0x74, 0x49, 0xee, 0x35, 0x54, 0x82, 0x38, 0xa5, 0xf1, 0xe1, 0x27, 0x4b, 0x40, 0x7b, 0x8a,
+ 0x42, 0x91, 0x23, 0x57, 0xdf, 0x44, 0x05, 0xa0, 0x15, 0xae, 0xa0, 0xc2, 0x06, 0xf3, 0x7d, 0xf6,
+ 0x1c, 0xae, 0xa2, 0xd2, 0xc6, 0x81, 0x6b, 0x47, 0xc4, 0x99, 0xd5, 0x70, 0x09, 0x4d, 0xdc, 0xbe,
+ 0x7d, 0x6b, 0x36, 0x87, 0xe7, 0xd1, 0xec, 0xab, 0xc4, 0x74, 0xba, 0xae, 0x47, 0x36, 0x1e, 0xf0,
+ 0x43, 0x64, 0x76, 0x02, 0x4f, 0xa2, 0x72, 0x8b, 0xec, 0x11, 0x68, 0x9c, 0x5f, 0xfd, 0x54, 0x43,
+ 0x05, 0x9e, 0xcd, 0x13, 0x34, 0xf3, 0x3a, 0x89, 0x38, 0x1f, 0x00, 0x09, 0x31, 0x4e, 0xcf, 0xab,
+ 0x94, 0x22, 0xb5, 0x0b, 0x43, 0x9e, 0x29, 0x9c, 0xad, 0x5f, 0xf9, 0xf1, 0x27, 0xff, 0xfe, 0x75,
+ 0xee, 0x72, 0x5d, 0x6f, 0x1e, 0x7c, 0xab, 0xb9, 0x47, 0xad, 0x6b, 0x21, 0x89, 0x9a, 0x0f, 0x21,
+ 0x30, 0x1f, 0x34, 0x1f, 0xba, 0xce, 0x07, 0x37, 0xb4, 0xab, 0x2f, 0x6a, 0xf8, 0x06, 0x2a, 0x40,
+ 0x78, 0x31, 0x27, 0xac, 0x1c, 0xea, 0xa3, 0x6d, 0x4f, 0xfc, 0x34, 0xa7, 0x81, 0x6e, 0xf1, 0x0d,
+ 0xf8, 0xe9, 0x08, 0x5e, 0x7c, 0x22, 0xb9, 0xdf, 0x60, 0x41, 0xaa, 0xf1, 0xdd, 0x9a, 0x37, 0x5a,
+ 0xdf, 0x25, 0xf6, 0x7e, 0x8b, 0x84, 0x3e, 0xf5, 0x42, 0xb2, 0xf6, 0xce, 0xdf, 0x1f, 0x2d, 0x69,
+ 0x1f, 0x3d, 0x5a, 0xd2, 0xfe, 0xf9, 0x68, 0x49, 0xfb, 0xc5, 0xe3, 0xa5, 0x73, 0x1f, 0x3d, 0x5e,
+ 0x3a, 0xf7, 0x8f, 0xc7, 0x4b, 0xe7, 0x7e, 0xf8, 0xcd, 0x8e, 0x1b, 0xed, 0xc6, 0x56, 0xc3, 0xa6,
+ 0xbd, 0xa6, 0x19, 0xf4, 0x4c, 0xc7, 0xf4, 0x03, 0xca, 0x02, 0x24, 0xfe, 0x4a, 0x7e, 0x51, 0xf2,
+ 0xa7, 0xdc, 0xfc, 0x4d, 0x00, 0xee, 0x70, 0x71, 0x63, 0x93, 0x36, 0x6e, 0xfa, 0xae, 0x55, 0x04,
+ 0x1f, 0xae, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x4c, 0x88, 0xf9, 0x94, 0x30, 0x33, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -4075,6 +4085,32 @@ func (m *JobUtilisationEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.AvgResourcesForPeriod) > 0 {
+ for k := range m.AvgResourcesForPeriod {
+ v := m.AvgResourcesForPeriod[k]
+ baseI := i
+ if v != nil {
+ {
+ size, err := v.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintEvent(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ i -= len(k)
+ copy(dAtA[i:], k)
+ i = encodeVarintEvent(dAtA, i, uint64(len(k)))
+ i--
+ dAtA[i] = 0xa
+ i = encodeVarintEvent(dAtA, i, uint64(baseI-i))
+ i--
+ dAtA[i] = 0x6a
+ }
+ }
if len(m.TotalCumulativeUsage) > 0 {
for k := range m.TotalCumulativeUsage {
v := m.TotalCumulativeUsage[k]
@@ -5827,6 +5863,19 @@ func (m *JobUtilisationEvent) Size() (n int) {
n += mapEntrySize + 1 + sovEvent(uint64(mapEntrySize))
}
}
+ if len(m.AvgResourcesForPeriod) > 0 {
+ for k, v := range m.AvgResourcesForPeriod {
+ _ = k
+ _ = v
+ l = 0
+ if v != nil {
+ l = v.Size()
+ l += 1 + sovEvent(uint64(l))
+ }
+ mapEntrySize := 1 + len(k) + sovEvent(uint64(len(k))) + l
+ n += mapEntrySize + 1 + sovEvent(uint64(mapEntrySize))
+ }
+ }
return n
}
@@ -11110,6 +11159,135 @@ func (m *JobUtilisationEvent) Unmarshal(dAtA []byte) error {
}
m.TotalCumulativeUsage[mapkey] = mapvalue
iNdEx = postIndex
+ case 13:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AvgResourcesForPeriod", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowEvent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthEvent
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthEvent
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.AvgResourcesForPeriod == nil {
+ m.AvgResourcesForPeriod = make(map[string]*resource.Quantity)
+ }
+ var mapkey string
+ var mapvalue *resource.Quantity
+ for iNdEx < postIndex {
+ entryPreIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowEvent
+ }
+ 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 ErrIntOverflowEvent
+ }
+ 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 ErrInvalidLengthEvent
+ }
+ postStringIndexmapkey := iNdEx + intStringLenmapkey
+ if postStringIndexmapkey < 0 {
+ return ErrInvalidLengthEvent
+ }
+ 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 ErrIntOverflowEvent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ mapmsglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if mapmsglen < 0 {
+ return ErrInvalidLengthEvent
+ }
+ postmsgIndex := iNdEx + mapmsglen
+ if postmsgIndex < 0 {
+ return ErrInvalidLengthEvent
+ }
+ if postmsgIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ mapvalue = &resource.Quantity{}
+ if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
+ return err
+ }
+ iNdEx = postmsgIndex
+ } else {
+ iNdEx = entryPreIndex
+ skippy, err := skipEvent(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthEvent
+ }
+ if (iNdEx + skippy) > postIndex {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+ m.AvgResourcesForPeriod[mapkey] = mapvalue
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipEvent(dAtA[iNdEx:])
diff --git a/pkg/api/event.proto b/pkg/api/event.proto
index 553bc93832c..fbba7adf81b 100644
--- a/pkg/api/event.proto
+++ b/pkg/api/event.proto
@@ -170,6 +170,7 @@ message JobUtilisationEvent {
string pod_name = 10;
string pod_namespace = 11;
map total_cumulative_usage = 12;
+ map AvgResourcesForPeriod = 13;
}
message JobReprioritizingEvent {
diff --git a/pkg/api/job.pb.go b/pkg/api/job.pb.go
index 732a1ef53d1..cb776f8834b 100644
--- a/pkg/api/job.pb.go
+++ b/pkg/api/job.pb.go
@@ -199,6 +199,7 @@ type JobDetails struct {
LatestRunId string `protobuf:"bytes,10,opt,name=latest_run_id,json=latestRunId,proto3" json:"latestRunId,omitempty"`
JobSpec *Job `protobuf:"bytes,11,opt,name=job_spec,json=jobSpec,proto3" json:"jobSpec,omitempty"`
JobRuns []*JobRunDetails `protobuf:"bytes,12,rep,name=job_runs,json=jobRuns,proto3" json:"jobRuns,omitempty"`
+ CancelUser string `protobuf:"bytes,13,opt,name=cancel_user,json=cancelUser,proto3" json:"cancelUser,omitempty"`
}
func (m *JobDetails) Reset() { *m = JobDetails{} }
@@ -318,6 +319,13 @@ func (m *JobDetails) GetJobRuns() []*JobRunDetails {
return nil
}
+func (m *JobDetails) GetCancelUser() string {
+ if m != nil {
+ return m.CancelUser
+ }
+ return ""
+}
+
type JobDetailsRequest struct {
JobIds []string `protobuf:"bytes,1,rep,name=job_ids,json=jobIds,proto3" json:"jobIds,omitempty"`
ExpandJobSpec bool `protobuf:"varint,2,opt,name=expand_job_spec,json=expandJobSpec,proto3" json:"expandJobSpec,omitempty"`
@@ -768,95 +776,96 @@ func init() {
func init() { proto.RegisterFile("pkg/api/job.proto", fileDescriptor_e45f6b75bfad87a4) }
var fileDescriptor_e45f6b75bfad87a4 = []byte{
- // 1399 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdf, 0x6b, 0xdb, 0x56,
- 0x14, 0x8e, 0x9c, 0x38, 0xb1, 0xaf, 0xeb, 0x44, 0xb9, 0xf9, 0xe5, 0xb8, 0x9d, 0x95, 0xa9, 0xac,
- 0x4d, 0x4b, 0x6b, 0xb3, 0x8c, 0x41, 0xc9, 0x28, 0x5b, 0x12, 0xab, 0x25, 0x59, 0xe7, 0x06, 0xc5,
- 0x66, 0x65, 0x6c, 0x18, 0xc9, 0xbe, 0x4d, 0xe5, 0xda, 0x92, 0xaa, 0x7b, 0x55, 0x1a, 0xd8, 0xd3,
- 0x60, 0x0f, 0x7b, 0xdb, 0xe8, 0xd3, 0xfe, 0xa1, 0xb1, 0x3d, 0x0c, 0x0a, 0x7b, 0xe9, 0x93, 0x18,
- 0xed, 0x60, 0xa0, 0xa7, 0xfd, 0x09, 0x43, 0xf7, 0x4a, 0xf2, 0xbd, 0x4a, 0x82, 0xd3, 0x3e, 0xfa,
- 0x3b, 0xe7, 0x7c, 0xf7, 0x9e, 0x73, 0xbe, 0x7b, 0x8e, 0x0c, 0x16, 0xdd, 0xa7, 0xc7, 0x0d, 0xc3,
- 0xb5, 0x1a, 0x03, 0xc7, 0xac, 0xbb, 0x9e, 0x43, 0x1c, 0x38, 0x6d, 0xb8, 0x56, 0x75, 0x39, 0xc1,
- 0xb1, 0x6f, 0x8e, 0x2c, 0xc2, 0x4c, 0x55, 0xe5, 0xd8, 0x71, 0x8e, 0x87, 0xa8, 0x41, 0x7f, 0x99,
- 0xfe, 0xe3, 0x06, 0xb1, 0x46, 0x08, 0x13, 0x63, 0xe4, 0xc6, 0x0e, 0x57, 0x62, 0x87, 0x28, 0xd2,
- 0xb0, 0x6d, 0x87, 0x18, 0xc4, 0x72, 0x6c, 0xcc, 0xac, 0xea, 0x9f, 0x33, 0xa0, 0x7c, 0xe0, 0x98,
- 0xba, 0x6f, 0x37, 0x11, 0x31, 0xac, 0x21, 0x86, 0x37, 0xc1, 0xac, 0xe7, 0xdb, 0x5d, 0xab, 0x5f,
- 0x91, 0x36, 0xa4, 0xcd, 0xe2, 0xee, 0x52, 0x18, 0x28, 0x0b, 0x9e, 0x6f, 0xef, 0xf7, 0x6f, 0x39,
- 0x23, 0x8b, 0xa0, 0x91, 0x4b, 0x4e, 0xf4, 0x3c, 0x05, 0x22, 0xdf, 0x81, 0x63, 0x46, 0xbe, 0xb9,
- 0xb1, 0xef, 0xc0, 0x31, 0x45, 0x5f, 0x0a, 0xc0, 0xcf, 0x40, 0x1e, 0x13, 0x83, 0xa0, 0xca, 0xf4,
- 0x86, 0xb4, 0x39, 0xbf, 0x25, 0xd7, 0x0d, 0xd7, 0xaa, 0xb3, 0xa3, 0x8f, 0x22, 0x9c, 0x05, 0x53,
- 0x17, 0x3e, 0x98, 0x02, 0xb0, 0x01, 0xe6, 0x7a, 0x43, 0x1f, 0x13, 0xe4, 0x55, 0x66, 0xe8, 0x49,
- 0x2b, 0x61, 0xa0, 0x2c, 0xc6, 0x10, 0xe7, 0x9e, 0x78, 0xc1, 0x6b, 0x60, 0xc6, 0x76, 0xfa, 0xa8,
- 0x92, 0xa7, 0xde, 0x30, 0x0c, 0x94, 0xf9, 0xe8, 0x37, 0xe7, 0x4a, 0xed, 0xf0, 0x21, 0x28, 0x0e,
- 0x91, 0x81, 0x51, 0xbf, 0x4b, 0x70, 0x65, 0x6e, 0x43, 0xda, 0x2c, 0x6d, 0x55, 0xeb, 0xac, 0x62,
- 0xf5, 0xa4, 0xa4, 0xf5, 0x76, 0x52, 0xd2, 0xdd, 0xd5, 0x30, 0x50, 0x20, 0x0b, 0x68, 0x63, 0x8e,
- 0xac, 0x90, 0x60, 0x50, 0x07, 0xc0, 0x45, 0x76, 0xdf, 0xb2, 0x8f, 0x23, 0xc6, 0xc2, 0x44, 0xc6,
- 0xb5, 0x30, 0x50, 0x96, 0xe2, 0x08, 0x81, 0xb2, 0x98, 0x82, 0x11, 0x27, 0x26, 0x86, 0x47, 0xd8,
- 0x2d, 0x8b, 0x17, 0xe3, 0x8c, 0x23, 0x44, 0xce, 0x14, 0x84, 0x1d, 0x50, 0x7a, 0x6c, 0xd9, 0x16,
- 0x7e, 0xc2, 0x48, 0xc1, 0x44, 0xd2, 0x4a, 0x18, 0x28, 0xcb, 0x49, 0x88, 0xc0, 0x0a, 0xc6, 0xa8,
- 0xfa, 0xeb, 0x2c, 0x00, 0x07, 0x8e, 0xc9, 0x89, 0x29, 0x16, 0x88, 0x34, 0x51, 0x20, 0x37, 0x40,
- 0xfe, 0x99, 0x8f, 0x7c, 0xc4, 0x6b, 0x89, 0x02, 0xbc, 0x2b, 0x05, 0xe0, 0x2d, 0x4a, 0x8b, 0x11,
- 0xa1, 0x62, 0x2a, 0xee, 0x2e, 0x87, 0x81, 0x22, 0x33, 0x84, 0x73, 0x8e, 0x7d, 0xe0, 0xa7, 0xa0,
- 0x68, 0x1b, 0x23, 0x84, 0x5d, 0xa3, 0x87, 0x62, 0xf9, 0xd0, 0x0a, 0xa5, 0x20, 0x5f, 0xa1, 0x14,
- 0x84, 0x77, 0x12, 0xc1, 0xe6, 0xa9, 0x60, 0xcb, 0x89, 0x60, 0x27, 0xab, 0xf5, 0x11, 0xb8, 0xc4,
- 0xde, 0x68, 0xdc, 0xb1, 0xd9, 0x89, 0xc5, 0x5d, 0x0f, 0x03, 0x65, 0x25, 0x8d, 0x11, 0xaa, 0x5b,
- 0xe2, 0xe0, 0x48, 0xae, 0x3d, 0xc3, 0xee, 0xa1, 0xe1, 0x3b, 0xc8, 0x95, 0x05, 0x88, 0x72, 0x4d,
- 0x30, 0xf8, 0x39, 0x28, 0xc7, 0x84, 0x1e, 0x32, 0xb0, 0x63, 0x53, 0xc5, 0x16, 0x77, 0xab, 0x61,
- 0xa0, 0xac, 0x32, 0x83, 0x4e, 0x71, 0x2e, 0xf8, 0x12, 0x8f, 0xc3, 0x27, 0x00, 0x0e, 0x0d, 0x4c,
- 0xba, 0xc4, 0x33, 0x6c, 0x6c, 0x45, 0xa3, 0xe5, 0x62, 0x1a, 0xad, 0x85, 0x81, 0x52, 0x8d, 0x22,
- 0xdb, 0x69, 0xa0, 0x70, 0x45, 0x39, 0x6b, 0x83, 0x77, 0x41, 0x79, 0x68, 0x10, 0x84, 0x49, 0x37,
- 0x9e, 0x4f, 0x80, 0x5e, 0x95, 0x96, 0x8e, 0x19, 0xf4, 0xcc, 0x94, 0x2a, 0x71, 0x30, 0xdc, 0x06,
- 0x85, 0x48, 0x8a, 0xd8, 0x45, 0xbd, 0x4a, 0x89, 0x5e, 0xaf, 0x90, 0x74, 0x94, 0x4d, 0x93, 0x81,
- 0x63, 0x1e, 0xb9, 0xa8, 0xc7, 0x4f, 0x93, 0x18, 0x82, 0x4d, 0x16, 0xeb, 0xf9, 0x36, 0xae, 0x5c,
- 0xda, 0x98, 0xde, 0x2c, 0x6d, 0x41, 0x6e, 0x7c, 0xc5, 0x62, 0x4f, 0x59, 0x74, 0xdf, 0xc6, 0x19,
- 0x96, 0x08, 0x52, 0xff, 0x90, 0xc0, 0xe2, 0xf8, 0x6d, 0xe8, 0xe8, 0x99, 0x8f, 0x30, 0x81, 0xb7,
- 0xc1, 0x1c, 0x7b, 0x22, 0xb8, 0x22, 0x6d, 0x4c, 0x73, 0x62, 0xde, 0xef, 0xe3, 0x8c, 0x98, 0xf7,
- 0xfb, 0x18, 0xee, 0x81, 0x05, 0xf4, 0xc2, 0x35, 0xec, 0x7e, 0x37, 0xcd, 0x26, 0x7a, 0x2f, 0x85,
- 0xdd, 0xcb, 0x61, 0xa0, 0xac, 0x31, 0xd3, 0xc1, 0xa9, 0x4c, 0xca, 0x82, 0x01, 0x7e, 0x01, 0xe6,
- 0x39, 0x12, 0xcf, 0xb7, 0xe9, 0x3b, 0x2a, 0xb0, 0xb6, 0xa7, 0xae, 0xba, 0x2f, 0xb4, 0x9d, 0xc7,
- 0xd5, 0xff, 0x24, 0x00, 0xf9, 0x5c, 0xb0, 0xeb, 0xd8, 0x18, 0x41, 0x13, 0x94, 0x22, 0xc6, 0x3e,
- 0x83, 0x69, 0x42, 0xa5, 0xad, 0xeb, 0x49, 0xad, 0x32, 0xde, 0x1c, 0xa4, 0xd9, 0xc4, 0x3b, 0x61,
- 0x23, 0x66, 0x90, 0x82, 0xfc, 0x88, 0x19, 0xa3, 0xd5, 0xe7, 0x60, 0x21, 0x13, 0x08, 0xaf, 0x82,
- 0xe9, 0xa7, 0xe8, 0x24, 0x9e, 0x31, 0x8b, 0x61, 0xa0, 0x94, 0x9f, 0xa2, 0x13, 0x2e, 0x3c, 0xb2,
- 0xc2, 0x6d, 0x90, 0x7f, 0x6e, 0x0c, 0xe3, 0xf9, 0x52, 0xda, 0x5a, 0xc8, 0xdc, 0x8a, 0xbd, 0x68,
- 0xea, 0xc1, 0xbf, 0x68, 0x0a, 0x6c, 0xe7, 0xee, 0x48, 0xea, 0x4f, 0x39, 0xb0, 0x22, 0x34, 0x3c,
- 0xcd, 0xda, 0x03, 0x0b, 0x71, 0x1d, 0x33, 0x99, 0xdf, 0x3e, 0xad, 0x12, 0x3e, 0xf9, 0x31, 0xca,
- 0xf2, 0xa7, 0x2d, 0x1c, 0xf0, 0x38, 0xdf, 0x42, 0xc1, 0x50, 0xfd, 0x9e, 0xd6, 0x3f, 0xc3, 0x70,
- 0xb1, 0x42, 0xdc, 0x15, 0x0b, 0x71, 0x96, 0x94, 0x27, 0xd5, 0x42, 0x03, 0xcb, 0x99, 0xac, 0x52,
- 0x31, 0xb3, 0xc7, 0x29, 0x88, 0x99, 0x7e, 0x2c, 0x08, 0x62, 0x66, 0x88, 0xba, 0x03, 0xe4, 0x03,
- 0xc7, 0xd4, 0x3c, 0xcf, 0xf1, 0xde, 0xf3, 0x3d, 0xa8, 0xaf, 0xd9, 0xa3, 0x4a, 0x38, 0xe2, 0x8e,
- 0x7c, 0x07, 0x22, 0xc5, 0x74, 0x11, 0x45, 0xe3, 0x66, 0x7c, 0x94, 0xe4, 0x29, 0xfa, 0x8e, 0x11,
- 0xd6, 0x04, 0xba, 0x1a, 0x06, 0x09, 0xc6, 0xaf, 0x86, 0x14, 0xac, 0xf6, 0xc1, 0xbc, 0x18, 0x75,
- 0xb1, 0xc2, 0xdf, 0xe0, 0x0b, 0x5f, 0x9c, 0x58, 0x64, 0x56, 0x9d, 0x68, 0xdd, 0xf8, 0xef, 0x5b,
- 0x9d, 0xdf, 0x24, 0x70, 0x35, 0xe5, 0xe8, 0x60, 0xcb, 0x3e, 0xd6, 0x5e, 0x10, 0xe4, 0xd9, 0xc6,
- 0xf0, 0xc0, 0x31, 0x3b, 0x9e, 0x95, 0xd0, 0xa6, 0xbb, 0x57, 0x7a, 0x87, 0xdd, 0x9b, 0xbb, 0xc0,
- 0xee, 0xbd, 0x07, 0x64, 0x14, 0x9f, 0x48, 0x67, 0x8d, 0xef, 0x59, 0xf1, 0xce, 0xbe, 0x12, 0x06,
- 0x4a, 0x05, 0x09, 0xb7, 0xe1, 0xe2, 0xe7, 0x45, 0x8b, 0xfa, 0x2f, 0x6b, 0x73, 0x52, 0x0c, 0xb1,
- 0xcd, 0x74, 0xeb, 0x9e, 0x6a, 0xb3, 0xe8, 0x9b, 0x6e, 0xee, 0x4c, 0x9b, 0x19, 0x96, 0x69, 0x33,
- 0x03, 0xab, 0x98, 0xb6, 0x99, 0x8b, 0xba, 0x58, 0x9b, 0xef, 0xf0, 0x6d, 0x3e, 0xfb, 0xc3, 0xe1,
- 0xfc, 0xae, 0xdf, 0xfc, 0x31, 0x07, 0x4a, 0xdc, 0x67, 0x31, 0x5c, 0x01, 0x8b, 0x7a, 0xa7, 0xd5,
- 0x3d, 0x6a, 0xef, 0xb4, 0xb5, 0x6e, 0xa7, 0xf5, 0x65, 0xeb, 0xe1, 0xd7, 0x2d, 0x79, 0x0a, 0x2e,
- 0x03, 0x79, 0x0c, 0x3f, 0xd0, 0x76, 0x8e, 0xb4, 0xa6, 0x2c, 0x89, 0xce, 0x87, 0x5a, 0xab, 0xb9,
- 0xdf, 0xba, 0x2f, 0xe7, 0x44, 0x58, 0xef, 0xb4, 0x5a, 0x11, 0x3c, 0x0d, 0xd7, 0xc0, 0xd2, 0x18,
- 0x3e, 0xea, 0xec, 0xed, 0x69, 0x5a, 0x53, 0x6b, 0xca, 0x33, 0x22, 0xf9, 0xbd, 0x9d, 0xfd, 0x07,
- 0x5a, 0x53, 0xce, 0x8b, 0xee, 0x87, 0xba, 0xa6, 0x7d, 0x75, 0xd8, 0xd6, 0x9a, 0xf2, 0xac, 0x68,
- 0xd8, 0xdb, 0x69, 0xed, 0x69, 0x0f, 0xa2, 0x88, 0x39, 0x78, 0x19, 0xac, 0x65, 0x2e, 0xd9, 0xd5,
- 0x1e, 0x1d, 0xee, 0xeb, 0x5a, 0x53, 0x2e, 0xc0, 0x0f, 0xc0, 0xba, 0xde, 0x69, 0x1d, 0x09, 0x56,
- 0x5d, 0x6b, 0x77, 0xf4, 0x96, 0xd6, 0x94, 0x8b, 0x5b, 0x2f, 0x67, 0xc0, 0xcc, 0x81, 0x63, 0xe2,
- 0xe8, 0x6b, 0xea, 0x3e, 0x22, 0x69, 0x43, 0xe1, 0x4a, 0xb6, 0xc1, 0x54, 0xc2, 0xd5, 0xd5, 0xb3,
- 0xfb, 0xae, 0xae, 0xff, 0xf0, 0xd7, 0x3f, 0x2f, 0x73, 0x4b, 0xea, 0x7c, 0xe3, 0xf9, 0xc7, 0xd1,
- 0x5f, 0xaa, 0x06, 0xa6, 0xf6, 0x6d, 0xe9, 0x26, 0xfc, 0x45, 0x02, 0x0a, 0x4f, 0x7d, 0xc6, 0x03,
- 0x81, 0x9b, 0x22, 0xed, 0xf9, 0x6f, 0xe8, 0xdc, 0x0b, 0xdc, 0xa2, 0x17, 0xb8, 0xa6, 0x7e, 0x28,
- 0x5e, 0xe0, 0x0c, 0xa6, 0xe8, 0x4e, 0xdf, 0x82, 0x32, 0xbb, 0x52, 0xf2, 0x09, 0xbd, 0x7a, 0x6a,
- 0x7b, 0xb2, 0xe3, 0xd6, 0xce, 0xd9, 0xaa, 0x6a, 0x95, 0x9e, 0xb7, 0xac, 0x2e, 0x24, 0xe7, 0xc5,
- 0x3b, 0x29, 0x62, 0x4f, 0x6b, 0xc9, 0x66, 0xd7, 0xb8, 0x96, 0xc2, 0x0c, 0x1e, 0xa7, 0x22, 0x8e,
- 0xca, 0xd3, 0xb5, 0x64, 0x03, 0x36, 0x62, 0x46, 0x40, 0x66, 0xcc, 0xdc, 0x5f, 0xc9, 0xf5, 0xb3,
- 0xd6, 0x1f, 0x3b, 0xa1, 0x7a, 0xfe, 0x66, 0x14, 0x13, 0xf0, 0x7c, 0x9b, 0x4b, 0x60, 0x77, 0xe7,
- 0xf7, 0x37, 0x35, 0xe9, 0xd5, 0x9b, 0x9a, 0xf4, 0xf7, 0x9b, 0x9a, 0xf4, 0xf3, 0xdb, 0xda, 0xd4,
- 0xab, 0xb7, 0xb5, 0xa9, 0xd7, 0x6f, 0x6b, 0x53, 0xdf, 0x5c, 0x3f, 0xb6, 0xc8, 0x13, 0xdf, 0xac,
- 0xf7, 0x9c, 0x51, 0xc3, 0xf0, 0x46, 0x46, 0xdf, 0x70, 0x3d, 0x67, 0x80, 0x7a, 0x24, 0xfe, 0xd5,
- 0x88, 0xff, 0x3e, 0x9b, 0xb3, 0xf4, 0x6b, 0xf4, 0x93, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xd7,
- 0x8d, 0xdd, 0xf9, 0x68, 0x0f, 0x00, 0x00,
+ // 1420 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x5f, 0x6b, 0xdb, 0xd6,
+ 0x1b, 0x8e, 0x9c, 0x38, 0xb1, 0x8f, 0xeb, 0x44, 0x39, 0xf9, 0xe7, 0xb8, 0xfd, 0x59, 0xf9, 0xa9,
+ 0xac, 0x4d, 0x4b, 0x6b, 0xb3, 0x8c, 0x41, 0x97, 0x51, 0xb6, 0x24, 0x56, 0x4b, 0xb2, 0xce, 0x0d,
+ 0x8a, 0xcd, 0xca, 0xd8, 0x30, 0x92, 0x7d, 0x9a, 0xca, 0xb5, 0x25, 0x55, 0xe7, 0xa8, 0x34, 0xb0,
+ 0xab, 0xc1, 0x2e, 0x76, 0xb7, 0xd1, 0xef, 0x34, 0xb6, 0x8b, 0x41, 0x61, 0xbb, 0xe8, 0x95, 0x18,
+ 0xed, 0x60, 0xa0, 0xab, 0x7d, 0x84, 0xa1, 0x73, 0x24, 0xf9, 0x1c, 0x25, 0xc1, 0x69, 0x2f, 0xfd,
+ 0xbc, 0xef, 0xfb, 0x9c, 0x73, 0x9e, 0xf7, 0x9f, 0x0c, 0x16, 0xdd, 0xa7, 0xc7, 0x0d, 0xc3, 0xb5,
+ 0x1a, 0x03, 0xc7, 0xac, 0xbb, 0x9e, 0x43, 0x1c, 0x38, 0x6d, 0xb8, 0x56, 0x75, 0x39, 0xc1, 0xb1,
+ 0x6f, 0x8e, 0x2c, 0xc2, 0x4c, 0x55, 0xe5, 0xd8, 0x71, 0x8e, 0x87, 0xa8, 0x41, 0x7f, 0x99, 0xfe,
+ 0xe3, 0x06, 0xb1, 0x46, 0x08, 0x13, 0x63, 0xe4, 0xc6, 0x0e, 0x57, 0x62, 0x87, 0x28, 0xd2, 0xb0,
+ 0x6d, 0x87, 0x18, 0xc4, 0x72, 0x6c, 0xcc, 0xac, 0xea, 0xef, 0x33, 0xa0, 0x7c, 0xe0, 0x98, 0xba,
+ 0x6f, 0x37, 0x11, 0x31, 0xac, 0x21, 0x86, 0x37, 0xc1, 0xac, 0xe7, 0xdb, 0x5d, 0xab, 0x5f, 0x91,
+ 0x36, 0xa4, 0xcd, 0xe2, 0xee, 0x52, 0x18, 0x28, 0x0b, 0x9e, 0x6f, 0xef, 0xf7, 0x6f, 0x39, 0x23,
+ 0x8b, 0xa0, 0x91, 0x4b, 0x4e, 0xf4, 0x3c, 0x05, 0x22, 0xdf, 0x81, 0x63, 0x46, 0xbe, 0xb9, 0xb1,
+ 0xef, 0xc0, 0x31, 0x45, 0x5f, 0x0a, 0xc0, 0x4f, 0x41, 0x1e, 0x13, 0x83, 0xa0, 0xca, 0xf4, 0x86,
+ 0xb4, 0x39, 0xbf, 0x25, 0xd7, 0x0d, 0xd7, 0xaa, 0xb3, 0xa3, 0x8f, 0x22, 0x9c, 0x05, 0x53, 0x17,
+ 0x3e, 0x98, 0x02, 0xb0, 0x01, 0xe6, 0x7a, 0x43, 0x1f, 0x13, 0xe4, 0x55, 0x66, 0xe8, 0x49, 0x2b,
+ 0x61, 0xa0, 0x2c, 0xc6, 0x10, 0xe7, 0x9e, 0x78, 0xc1, 0x6b, 0x60, 0xc6, 0x76, 0xfa, 0xa8, 0x92,
+ 0xa7, 0xde, 0x30, 0x0c, 0x94, 0xf9, 0xe8, 0x37, 0xe7, 0x4a, 0xed, 0xf0, 0x21, 0x28, 0x0e, 0x91,
+ 0x81, 0x51, 0xbf, 0x4b, 0x70, 0x65, 0x6e, 0x43, 0xda, 0x2c, 0x6d, 0x55, 0xeb, 0x4c, 0xb1, 0x7a,
+ 0x22, 0x69, 0xbd, 0x9d, 0x48, 0xba, 0xbb, 0x1a, 0x06, 0x0a, 0x64, 0x01, 0x6d, 0xcc, 0x91, 0x15,
+ 0x12, 0x0c, 0xea, 0x00, 0xb8, 0xc8, 0xee, 0x5b, 0xf6, 0x71, 0xc4, 0x58, 0x98, 0xc8, 0xb8, 0x16,
+ 0x06, 0xca, 0x52, 0x1c, 0x21, 0x50, 0x16, 0x53, 0x30, 0xe2, 0xc4, 0xc4, 0xf0, 0x08, 0xbb, 0x65,
+ 0xf1, 0x62, 0x9c, 0x71, 0x84, 0xc8, 0x99, 0x82, 0xb0, 0x03, 0x4a, 0x8f, 0x2d, 0xdb, 0xc2, 0x4f,
+ 0x18, 0x29, 0x98, 0x48, 0x5a, 0x09, 0x03, 0x65, 0x39, 0x09, 0x11, 0x58, 0xc1, 0x18, 0x55, 0xff,
+ 0x9c, 0x05, 0xe0, 0xc0, 0x31, 0xb9, 0x62, 0x8a, 0x0b, 0x44, 0x9a, 0x58, 0x20, 0x37, 0x40, 0xfe,
+ 0x99, 0x8f, 0x7c, 0xc4, 0xd7, 0x12, 0x05, 0x78, 0x57, 0x0a, 0xc0, 0x5b, 0x94, 0x16, 0x23, 0x42,
+ 0x8b, 0xa9, 0xb8, 0xbb, 0x1c, 0x06, 0x8a, 0xcc, 0x10, 0xce, 0x39, 0xf6, 0x81, 0x1f, 0x83, 0xa2,
+ 0x6d, 0x8c, 0x10, 0x76, 0x8d, 0x1e, 0x8a, 0xcb, 0x87, 0x2a, 0x94, 0x82, 0xbc, 0x42, 0x29, 0x08,
+ 0xef, 0x24, 0x05, 0x9b, 0xa7, 0x05, 0x5b, 0x4e, 0x0a, 0x76, 0x72, 0xb5, 0x3e, 0x02, 0x97, 0x58,
+ 0x8f, 0xc6, 0x19, 0x9b, 0x9d, 0x28, 0xee, 0x7a, 0x18, 0x28, 0x2b, 0x69, 0x8c, 0xa0, 0x6e, 0x89,
+ 0x83, 0xa3, 0x72, 0xed, 0x19, 0x76, 0x0f, 0x0d, 0xdf, 0xa1, 0x5c, 0x59, 0x80, 0x58, 0xae, 0x09,
+ 0x06, 0x3f, 0x03, 0xe5, 0x98, 0xd0, 0x43, 0x06, 0x76, 0x6c, 0x5a, 0xb1, 0xc5, 0xdd, 0x6a, 0x18,
+ 0x28, 0xab, 0xcc, 0xa0, 0x53, 0x9c, 0x0b, 0xbe, 0xc4, 0xe3, 0xf0, 0x09, 0x80, 0x43, 0x03, 0x93,
+ 0x2e, 0xf1, 0x0c, 0x1b, 0x5b, 0xd1, 0x68, 0xb9, 0x58, 0x8d, 0xd6, 0xc2, 0x40, 0xa9, 0x46, 0x91,
+ 0xed, 0x34, 0x50, 0xb8, 0xa2, 0x9c, 0xb5, 0xc1, 0xbb, 0xa0, 0x3c, 0x34, 0x08, 0xc2, 0xa4, 0x1b,
+ 0xcf, 0x27, 0x40, 0xaf, 0x4a, 0xa5, 0x63, 0x06, 0x3d, 0x33, 0xa5, 0x4a, 0x1c, 0x0c, 0xb7, 0x41,
+ 0x21, 0x2a, 0x45, 0xec, 0xa2, 0x5e, 0xa5, 0x44, 0xaf, 0x57, 0x48, 0x32, 0xca, 0xa6, 0xc9, 0xc0,
+ 0x31, 0x8f, 0x5c, 0xd4, 0xe3, 0xa7, 0x49, 0x0c, 0xc1, 0x26, 0x8b, 0xf5, 0x7c, 0x1b, 0x57, 0x2e,
+ 0x6d, 0x4c, 0x6f, 0x96, 0xb6, 0x20, 0x37, 0xbe, 0xe2, 0x62, 0x4f, 0x59, 0x74, 0xdf, 0xc6, 0x19,
+ 0x96, 0x08, 0x82, 0x9f, 0x80, 0x52, 0xac, 0xb5, 0x8f, 0x91, 0x57, 0x29, 0xd3, 0xeb, 0xd3, 0xb6,
+ 0x62, 0x70, 0x07, 0x0b, 0xb3, 0x0c, 0x8c, 0x51, 0xf5, 0x37, 0x09, 0x2c, 0x8e, 0xdb, 0x4a, 0x47,
+ 0xcf, 0x7c, 0x84, 0x09, 0xbc, 0x0d, 0xe6, 0x58, 0x77, 0xe1, 0x8a, 0xb4, 0x31, 0xcd, 0xf5, 0xc1,
+ 0x7e, 0x1f, 0x67, 0xfa, 0x60, 0xbf, 0x8f, 0xe1, 0x1e, 0x58, 0x40, 0x2f, 0x5c, 0xc3, 0xee, 0x77,
+ 0x53, 0x21, 0xa2, 0x56, 0x2b, 0xec, 0x5e, 0x0e, 0x03, 0x65, 0x8d, 0x99, 0x0e, 0x4e, 0x89, 0x50,
+ 0x16, 0x0c, 0xf0, 0x73, 0x30, 0xcf, 0x91, 0x78, 0xbe, 0x4d, 0x5b, 0xb0, 0xc0, 0x2a, 0x26, 0x75,
+ 0xd5, 0x7d, 0xa1, 0x62, 0x78, 0x5c, 0xfd, 0x57, 0x02, 0x90, 0x7f, 0x0b, 0x76, 0x1d, 0x1b, 0x23,
+ 0x68, 0x82, 0x52, 0xc4, 0xd8, 0x67, 0x30, 0x7d, 0x50, 0x69, 0xeb, 0x7a, 0x22, 0x73, 0xc6, 0x9b,
+ 0x83, 0x34, 0x9b, 0x78, 0x27, 0x4c, 0xc6, 0x41, 0x0a, 0xf2, 0x32, 0x8e, 0xd1, 0xea, 0x73, 0xb0,
+ 0x90, 0x09, 0x84, 0x57, 0xc1, 0xf4, 0x53, 0x74, 0x12, 0x8f, 0xa7, 0xc5, 0x30, 0x50, 0xca, 0x4f,
+ 0xd1, 0x09, 0x17, 0x1e, 0x59, 0xe1, 0x36, 0xc8, 0x3f, 0x37, 0x86, 0xf1, 0x68, 0x2a, 0x6d, 0x2d,
+ 0x64, 0x6e, 0xc5, 0x86, 0x01, 0xf5, 0xe0, 0x87, 0x01, 0x05, 0xb6, 0x73, 0x77, 0x24, 0xf5, 0xc7,
+ 0x1c, 0x58, 0x11, 0x6a, 0x25, 0x7d, 0xb5, 0x07, 0x16, 0x62, 0x1d, 0x33, 0x2f, 0xbf, 0x7d, 0xba,
+ 0xc0, 0xf8, 0xc7, 0x8f, 0x51, 0xf6, 0x7e, 0x9a, 0xc2, 0x01, 0x8f, 0xf3, 0x29, 0x14, 0x0c, 0xd5,
+ 0xef, 0xa8, 0xfe, 0x19, 0x86, 0x8b, 0x09, 0x71, 0x57, 0x14, 0xe2, 0xac, 0x2e, 0x98, 0xa4, 0x85,
+ 0x06, 0x96, 0x33, 0xaf, 0x4a, 0x8b, 0x99, 0xf5, 0xb5, 0x50, 0xcc, 0xf4, 0x3b, 0x43, 0x28, 0x66,
+ 0x86, 0xa8, 0x3b, 0x40, 0x3e, 0x70, 0x4c, 0xcd, 0xf3, 0x1c, 0xef, 0x3d, 0xfb, 0x41, 0x7d, 0xcd,
+ 0x9a, 0x2a, 0xe1, 0x88, 0x33, 0xf2, 0x2d, 0x88, 0x2a, 0xa6, 0x8b, 0x28, 0x1a, 0x27, 0xe3, 0x83,
+ 0xe4, 0x9d, 0xa2, 0xef, 0x18, 0x61, 0x49, 0xa0, 0x5b, 0x65, 0x90, 0x60, 0xfc, 0x56, 0x49, 0xc1,
+ 0x6a, 0x1f, 0xcc, 0x8b, 0x51, 0x17, 0x13, 0xfe, 0x06, 0x2f, 0x7c, 0x71, 0xa2, 0xc8, 0x4c, 0x9d,
+ 0x68, 0x53, 0xf9, 0xef, 0xab, 0xce, 0x2f, 0x12, 0xb8, 0x9a, 0x72, 0x74, 0xb0, 0x65, 0x1f, 0x6b,
+ 0x2f, 0x08, 0xf2, 0x6c, 0x63, 0x78, 0xe0, 0x98, 0x1d, 0xcf, 0x4a, 0x68, 0xd3, 0xb5, 0x2d, 0xbd,
+ 0xc3, 0xda, 0xce, 0x5d, 0x60, 0x6d, 0xdf, 0x03, 0x32, 0x8a, 0x4f, 0xa4, 0xb3, 0xc6, 0xf7, 0xac,
+ 0x78, 0xdd, 0x5f, 0x09, 0x03, 0xa5, 0x82, 0x84, 0xdb, 0x70, 0xf1, 0xf3, 0xa2, 0x45, 0xfd, 0x87,
+ 0xa5, 0x39, 0x11, 0x43, 0x4c, 0x33, 0x5d, 0xd8, 0xa7, 0xd2, 0x2c, 0xfa, 0xa6, 0x4b, 0x3f, 0x93,
+ 0x66, 0x86, 0x65, 0xd2, 0xcc, 0xc0, 0x2a, 0xa6, 0x69, 0xe6, 0xa2, 0x2e, 0x96, 0xe6, 0x3b, 0x7c,
+ 0x9a, 0xcf, 0xfe, 0xe6, 0x38, 0x3f, 0xeb, 0x37, 0x7f, 0xc8, 0x81, 0x12, 0xf7, 0x45, 0x0d, 0x57,
+ 0xc0, 0xa2, 0xde, 0x69, 0x75, 0x8f, 0xda, 0x3b, 0x6d, 0xad, 0xdb, 0x69, 0x7d, 0xd1, 0x7a, 0xf8,
+ 0x55, 0x4b, 0x9e, 0x82, 0xcb, 0x40, 0x1e, 0xc3, 0x0f, 0xb4, 0x9d, 0x23, 0xad, 0x29, 0x4b, 0xa2,
+ 0xf3, 0xa1, 0xd6, 0x6a, 0xee, 0xb7, 0xee, 0xcb, 0x39, 0x11, 0xd6, 0x3b, 0xad, 0x56, 0x04, 0x4f,
+ 0xc3, 0x35, 0xb0, 0x34, 0x86, 0x8f, 0x3a, 0x7b, 0x7b, 0x9a, 0xd6, 0xd4, 0x9a, 0xf2, 0x8c, 0x48,
+ 0x7e, 0x6f, 0x67, 0xff, 0x81, 0xd6, 0x94, 0xf3, 0xa2, 0xfb, 0xa1, 0xae, 0x69, 0x5f, 0x1e, 0xb6,
+ 0xb5, 0xa6, 0x3c, 0x2b, 0x1a, 0xf6, 0x76, 0x5a, 0x7b, 0xda, 0x83, 0x28, 0x62, 0x0e, 0x5e, 0x06,
+ 0x6b, 0x99, 0x4b, 0x76, 0xb5, 0x47, 0x87, 0xfb, 0xba, 0xd6, 0x94, 0x0b, 0xf0, 0x7f, 0x60, 0x5d,
+ 0xef, 0xb4, 0x8e, 0x04, 0xab, 0xae, 0xb5, 0x3b, 0x7a, 0x4b, 0x6b, 0xca, 0xc5, 0xad, 0x97, 0x33,
+ 0x60, 0xe6, 0xc0, 0x31, 0x71, 0xf4, 0x21, 0x76, 0x1f, 0x91, 0x34, 0xa1, 0x70, 0x25, 0x9b, 0x60,
+ 0x5a, 0xc2, 0xd5, 0xd5, 0xb3, 0xf3, 0xae, 0xae, 0x7f, 0xff, 0xc7, 0xdf, 0x2f, 0x73, 0x4b, 0xea,
+ 0x7c, 0xe3, 0xf9, 0x87, 0xd1, 0xbf, 0xb1, 0x06, 0xa6, 0xf6, 0x6d, 0xe9, 0x26, 0xfc, 0x59, 0x02,
+ 0x0a, 0x4f, 0x7d, 0x46, 0x83, 0xc0, 0x4d, 0x91, 0xf6, 0xfc, 0x1e, 0x3a, 0xf7, 0x02, 0xb7, 0xe8,
+ 0x05, 0xae, 0xa9, 0xff, 0x17, 0x2f, 0x70, 0x06, 0x53, 0x74, 0xa7, 0x6f, 0x40, 0x99, 0x5d, 0x29,
+ 0xf9, 0xfa, 0x5e, 0x3d, 0xb5, 0x3d, 0xd9, 0x71, 0x6b, 0xe7, 0x6c, 0x55, 0xb5, 0x4a, 0xcf, 0x5b,
+ 0x56, 0x17, 0x92, 0xf3, 0xe2, 0x9d, 0x14, 0xb1, 0xa7, 0x5a, 0xb2, 0xd9, 0x35, 0xd6, 0x52, 0x98,
+ 0xc1, 0xe3, 0xa7, 0x88, 0xa3, 0xf2, 0xb4, 0x96, 0x6c, 0xc0, 0x46, 0xcc, 0x08, 0xc8, 0x8c, 0x99,
+ 0xfb, 0x17, 0xba, 0x7e, 0xd6, 0xfa, 0x63, 0x27, 0x54, 0xcf, 0xdf, 0x8c, 0xe2, 0x03, 0x3c, 0xdf,
+ 0xe6, 0x1e, 0xb0, 0xbb, 0xf3, 0xeb, 0x9b, 0x9a, 0xf4, 0xea, 0x4d, 0x4d, 0xfa, 0xeb, 0x4d, 0x4d,
+ 0xfa, 0xe9, 0x6d, 0x6d, 0xea, 0xd5, 0xdb, 0xda, 0xd4, 0xeb, 0xb7, 0xb5, 0xa9, 0xaf, 0xaf, 0x1f,
+ 0x5b, 0xe4, 0x89, 0x6f, 0xd6, 0x7b, 0xce, 0xa8, 0x61, 0x78, 0x23, 0xa3, 0x6f, 0xb8, 0x9e, 0x33,
+ 0x40, 0x3d, 0x12, 0xff, 0x6a, 0xc4, 0xff, 0xbc, 0xcd, 0x59, 0xfa, 0x21, 0xfb, 0xd1, 0x7f, 0x01,
+ 0x00, 0x00, 0xff, 0xff, 0x07, 0xbf, 0x46, 0xec, 0xa3, 0x0f, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -1207,6 +1216,13 @@ func (m *JobDetails) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.CancelUser) > 0 {
+ i -= len(m.CancelUser)
+ copy(dAtA[i:], m.CancelUser)
+ i = encodeVarintJob(dAtA, i, uint64(len(m.CancelUser)))
+ i--
+ dAtA[i] = 0x6a
+ }
if len(m.JobRuns) > 0 {
for iNdEx := len(m.JobRuns) - 1; iNdEx >= 0; iNdEx-- {
{
@@ -1801,6 +1817,10 @@ func (m *JobDetails) Size() (n int) {
n += 1 + l + sovJob(uint64(l))
}
}
+ l = len(m.CancelUser)
+ if l > 0 {
+ n += 1 + l + sovJob(uint64(l))
+ }
return n
}
@@ -2734,6 +2754,38 @@ func (m *JobDetails) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
+ case 13:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CancelUser", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowJob
+ }
+ 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 ErrInvalidLengthJob
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthJob
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.CancelUser = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipJob(dAtA[iNdEx:])
diff --git a/pkg/api/job.proto b/pkg/api/job.proto
index 84366e08c1e..87f69908f1b 100644
--- a/pkg/api/job.proto
+++ b/pkg/api/job.proto
@@ -45,6 +45,7 @@ message JobDetails {
string latest_run_id = 10;
Job job_spec = 11; // Only filled in if expand_job_spec is true
repeated JobRunDetails job_runs = 12; // Only filled in if expand_job_run is true;
+ string cancel_user = 13;
}
message JobDetailsRequest {
diff --git a/pkg/armadaevents/events.pb.go b/pkg/armadaevents/events.pb.go
index 9a306a32f64..552b764daa3 100644
--- a/pkg/armadaevents/events.pb.go
+++ b/pkg/armadaevents/events.pb.go
@@ -549,6 +549,7 @@ type ResourceUtilisation struct {
TotalCumulativeUsage map[string]*resource.Quantity `protobuf:"bytes,5,rep,name=total_cumulative_usage,json=totalCumulativeUsage,proto3" json:"totalCumulativeUsage,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
JobId string `protobuf:"bytes,6,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"`
RunId string `protobuf:"bytes,7,opt,name=run_id,json=runId,proto3" json:"runId,omitempty"`
+ AvgResourcesForPeriod map[string]*resource.Quantity `protobuf:"bytes,8,rep,name=avg_resources_for_period,json=avgResourcesForPeriod,proto3" json:"avgResourcesForPeriod,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (m *ResourceUtilisation) Reset() { *m = ResourceUtilisation{} }
@@ -619,6 +620,13 @@ func (m *ResourceUtilisation) GetRunId() string {
return ""
}
+func (m *ResourceUtilisation) GetAvgResourcesForPeriod() map[string]*resource.Quantity {
+ if m != nil {
+ return m.AvgResourcesForPeriod
+ }
+ return nil
+}
+
// A request to run an Armada job. Each job consists of a set of Kubernetes objects,
// one of which is the main object (typically a pod spec.) and has a priority associated with it.
// When the main object exits, all other objects are cleaned up.
@@ -1549,8 +1557,9 @@ func (m *CancelJobSet) GetReason() string {
// Generated by the scheduler in response to CancelJob and CancelJobSet.
// One such message is generated per job that was cancelled.
type CancelledJob struct {
- Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`
- JobId string `protobuf:"bytes,3,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"`
+ Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`
+ JobId string `protobuf:"bytes,3,opt,name=job_id,json=jobId,proto3" json:"jobId,omitempty"`
+ CancelUser string `protobuf:"bytes,4,opt,name=cancel_user,json=cancelUser,proto3" json:"cancelUser,omitempty"`
}
func (m *CancelledJob) Reset() { *m = CancelledJob{} }
@@ -1600,6 +1609,13 @@ func (m *CancelledJob) GetJobId() string {
return ""
}
+func (m *CancelledJob) GetCancelUser() string {
+ if m != nil {
+ return m.CancelUser
+ }
+ return ""
+}
+
type JobSucceeded struct {
// Runtime information, e.g., which node the job is running on, its IP address etc,
// for each resource created for the job run.
@@ -3644,6 +3660,7 @@ func init() {
proto.RegisterType((*EventSequence)(nil), "armadaevents.EventSequence")
proto.RegisterType((*EventSequence_Event)(nil), "armadaevents.EventSequence.Event")
proto.RegisterType((*ResourceUtilisation)(nil), "armadaevents.ResourceUtilisation")
+ proto.RegisterMapType((map[string]*resource.Quantity)(nil), "armadaevents.ResourceUtilisation.AvgResourcesForPeriodEntry")
proto.RegisterMapType((map[string]*resource.Quantity)(nil), "armadaevents.ResourceUtilisation.MaxResourcesForPeriodEntry")
proto.RegisterMapType((map[string]*resource.Quantity)(nil), "armadaevents.ResourceUtilisation.TotalCumulativeUsageEntry")
proto.RegisterType((*SubmitJob)(nil), "armadaevents.SubmitJob")
@@ -3699,237 +3716,240 @@ func init() {
func init() { proto.RegisterFile("pkg/armadaevents/events.proto", fileDescriptor_6aab92ca59e015f8) }
var fileDescriptor_6aab92ca59e015f8 = []byte{
- // 3666 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3b, 0x4d, 0x6f, 0x1c, 0xc7,
- 0x95, 0xea, 0xf9, 0x9e, 0x37, 0xe4, 0x70, 0x54, 0xfc, 0xd0, 0x88, 0xb6, 0x38, 0xd4, 0xc8, 0xbb,
- 0x96, 0x0c, 0x7b, 0x28, 0xcb, 0xeb, 0x85, 0x3f, 0x16, 0x36, 0x38, 0x12, 0x2d, 0x89, 0x12, 0x25,
- 0x7a, 0x28, 0x79, 0xb5, 0x0b, 0x03, 0xe3, 0x9e, 0xe9, 0xe2, 0xb0, 0xc5, 0x99, 0xee, 0x76, 0x7f,
- 0xd0, 0x24, 0x60, 0xec, 0xda, 0x0b, 0xef, 0x9e, 0x7d, 0x59, 0x20, 0xc8, 0x25, 0xbe, 0xe4, 0xe0,
- 0x20, 0x39, 0x26, 0xd7, 0x5c, 0x73, 0x08, 0x02, 0x5f, 0x02, 0x04, 0x41, 0x3c, 0x08, 0x6c, 0xe4,
- 0x32, 0x87, 0xfc, 0x86, 0xa0, 0x3e, 0xba, 0xbb, 0xaa, 0xa7, 0x46, 0x24, 0x65, 0x51, 0x70, 0x9c,
- 0x13, 0xd9, 0xef, 0xbb, 0xeb, 0xbd, 0x7a, 0xfd, 0xde, 0xab, 0x1a, 0x38, 0xe7, 0xec, 0xf6, 0x56,
- 0x74, 0x77, 0xa0, 0x1b, 0x3a, 0xde, 0xc3, 0x96, 0xef, 0xad, 0xb0, 0x3f, 0x0d, 0xc7, 0xb5, 0x7d,
- 0x1b, 0x4d, 0x89, 0xa8, 0xc5, 0xfa, 0xee, 0x6b, 0x5e, 0xc3, 0xb4, 0x57, 0x74, 0xc7, 0x5c, 0xe9,
- 0xda, 0x2e, 0x5e, 0xd9, 0x7b, 0x79, 0xa5, 0x87, 0x2d, 0xec, 0xea, 0x3e, 0x36, 0x18, 0xc7, 0xe2,
- 0x45, 0x81, 0xc6, 0xc2, 0xfe, 0x47, 0xb6, 0xbb, 0x6b, 0x5a, 0x3d, 0x15, 0x65, 0xad, 0x67, 0xdb,
- 0xbd, 0x3e, 0x5e, 0xa1, 0x4f, 0x9d, 0x60, 0x7b, 0xc5, 0x37, 0x07, 0xd8, 0xf3, 0xf5, 0x81, 0xc3,
- 0x09, 0xfe, 0x25, 0x16, 0x35, 0xd0, 0xbb, 0x3b, 0xa6, 0x85, 0xdd, 0x83, 0x15, 0x6a, 0xaf, 0x63,
- 0xae, 0xb8, 0xd8, 0xb3, 0x03, 0xb7, 0x8b, 0xc7, 0xc4, 0xbe, 0x61, 0x5a, 0x3e, 0x76, 0x2d, 0xbd,
- 0xbf, 0xe2, 0x75, 0x77, 0xb0, 0x11, 0xf4, 0xb1, 0x1b, 0xff, 0x67, 0x77, 0x1e, 0xe2, 0xae, 0xef,
- 0x8d, 0x01, 0x18, 0x6f, 0xfd, 0xeb, 0x79, 0x98, 0x5e, 0x23, 0xef, 0xba, 0x85, 0x3f, 0x0c, 0xb0,
- 0xd5, 0xc5, 0xe8, 0x12, 0x64, 0x3f, 0x0c, 0x70, 0x80, 0xab, 0xda, 0xb2, 0x76, 0xb1, 0xd8, 0x9c,
- 0x1d, 0x0d, 0x6b, 0x33, 0x14, 0xf0, 0xa2, 0x3d, 0x30, 0x7d, 0x3c, 0x70, 0xfc, 0x83, 0x16, 0xa3,
- 0x40, 0x6f, 0xc0, 0xd4, 0x43, 0xbb, 0xd3, 0xf6, 0xb0, 0xdf, 0xb6, 0xf4, 0x01, 0xae, 0xa6, 0x28,
- 0x47, 0x75, 0x34, 0xac, 0xcd, 0x3d, 0xb4, 0x3b, 0x5b, 0xd8, 0xbf, 0xa3, 0x0f, 0x44, 0x36, 0x88,
- 0xa1, 0xe8, 0x25, 0xc8, 0x07, 0x1e, 0x76, 0xdb, 0xa6, 0x51, 0x4d, 0x53, 0xb6, 0xb9, 0xd1, 0xb0,
- 0x56, 0x21, 0xa0, 0x9b, 0x86, 0xc0, 0x92, 0x63, 0x10, 0xf4, 0x22, 0xe4, 0x7a, 0xae, 0x1d, 0x38,
- 0x5e, 0x35, 0xb3, 0x9c, 0x0e, 0xa9, 0x19, 0x44, 0xa4, 0x66, 0x10, 0x74, 0x17, 0x72, 0xcc, 0x81,
- 0xd5, 0xec, 0x72, 0xfa, 0x62, 0xe9, 0xca, 0xf9, 0x86, 0xe8, 0xd5, 0x86, 0xf4, 0xc2, 0xec, 0x89,
- 0x09, 0x64, 0x78, 0x51, 0x20, 0x8f, 0x83, 0x5f, 0xcd, 0x42, 0x96, 0xd2, 0xa1, 0x5b, 0x90, 0xef,
- 0xba, 0x98, 0xac, 0x7e, 0x15, 0x2d, 0x6b, 0x17, 0x4b, 0x57, 0x16, 0x1b, 0xcc, 0xab, 0x8d, 0xd0,
- 0xab, 0x8d, 0x7b, 0xa1, 0x57, 0x9b, 0xf3, 0xa3, 0x61, 0xed, 0x34, 0x27, 0x17, 0xa4, 0x86, 0x12,
- 0xd0, 0x26, 0x14, 0xbd, 0xa0, 0x33, 0x30, 0xfd, 0x75, 0xbb, 0x43, 0xd7, 0xbb, 0x74, 0xe5, 0x8c,
- 0x6c, 0xea, 0x56, 0x88, 0x6e, 0x9e, 0x19, 0x0d, 0x6b, 0xb3, 0x11, 0x75, 0x2c, 0xed, 0xc6, 0xa9,
- 0x56, 0x2c, 0x04, 0xed, 0xc0, 0x8c, 0x8b, 0x1d, 0xd7, 0xb4, 0x5d, 0xd3, 0x37, 0x3d, 0x4c, 0xe4,
- 0xa6, 0xa8, 0xdc, 0x73, 0xb2, 0xdc, 0x96, 0x4c, 0xd4, 0x3c, 0x37, 0x1a, 0xd6, 0xce, 0x26, 0x38,
- 0x25, 0x1d, 0x49, 0xb1, 0xc8, 0x07, 0x94, 0x00, 0x6d, 0x61, 0x9f, 0xfa, 0xb2, 0x74, 0x65, 0xf9,
- 0x91, 0xca, 0xb6, 0xb0, 0xdf, 0x5c, 0x1e, 0x0d, 0x6b, 0xcf, 0x8e, 0xf3, 0x4b, 0x2a, 0x15, 0xf2,
- 0x51, 0x1f, 0x2a, 0x22, 0xd4, 0x20, 0x2f, 0x98, 0xa1, 0x3a, 0x97, 0x26, 0xeb, 0x24, 0x54, 0xcd,
- 0xa5, 0xd1, 0xb0, 0xb6, 0x98, 0xe4, 0x95, 0xf4, 0x8d, 0x49, 0x26, 0xfe, 0xe9, 0xea, 0x56, 0x17,
- 0xf7, 0x89, 0x9a, 0xac, 0xca, 0x3f, 0x57, 0x43, 0x34, 0xf3, 0x4f, 0x44, 0x2d, 0xfb, 0x27, 0x02,
- 0xa3, 0xf7, 0x61, 0x2a, 0x7a, 0x20, 0xeb, 0x95, 0xe3, 0x31, 0xa4, 0x16, 0x4a, 0x56, 0x6a, 0x71,
- 0x34, 0xac, 0x2d, 0x88, 0x3c, 0x92, 0x68, 0x49, 0x5a, 0x2c, 0xbd, 0xcf, 0x56, 0x26, 0x3f, 0x59,
- 0x3a, 0xa3, 0x10, 0xa5, 0xf7, 0xc7, 0x57, 0x44, 0x92, 0x46, 0xa4, 0x93, 0x0d, 0x1c, 0x74, 0xbb,
- 0x18, 0x1b, 0xd8, 0xa8, 0x16, 0x54, 0xd2, 0xd7, 0x05, 0x0a, 0x26, 0x5d, 0xe4, 0x91, 0xa5, 0x8b,
- 0x18, 0xb2, 0xd6, 0x0f, 0xed, 0xce, 0x9a, 0xeb, 0xda, 0xae, 0x57, 0x2d, 0xaa, 0xd6, 0x7a, 0x3d,
- 0x44, 0xb3, 0xb5, 0x8e, 0xa8, 0xe5, 0xb5, 0x8e, 0xc0, 0xdc, 0xde, 0x56, 0x60, 0xdd, 0xc6, 0xba,
- 0x87, 0x8d, 0x2a, 0x4c, 0xb0, 0x37, 0xa2, 0x88, 0xec, 0x8d, 0x20, 0x63, 0xf6, 0x46, 0x18, 0x64,
- 0x40, 0x99, 0x3d, 0xaf, 0x7a, 0x9e, 0xd9, 0xb3, 0xb0, 0x51, 0x2d, 0x51, 0xf9, 0xcf, 0xaa, 0xe4,
- 0x87, 0x34, 0xcd, 0x67, 0x47, 0xc3, 0x5a, 0x55, 0xe6, 0x93, 0x74, 0x24, 0x64, 0xa2, 0x0f, 0x60,
- 0x9a, 0x41, 0x5a, 0x81, 0x65, 0x99, 0x56, 0xaf, 0x3a, 0x45, 0x95, 0x3c, 0xa3, 0x52, 0xc2, 0x49,
- 0x9a, 0xcf, 0x8c, 0x86, 0xb5, 0x33, 0x12, 0x97, 0xa4, 0x42, 0x16, 0x48, 0x32, 0x06, 0x03, 0xc4,
- 0x8e, 0x9d, 0x56, 0x65, 0x8c, 0x75, 0x99, 0x88, 0x65, 0x8c, 0x04, 0xa7, 0x9c, 0x31, 0x12, 0xc8,
- 0xd8, 0x1f, 0xdc, 0xc9, 0xe5, 0xc9, 0xfe, 0xe0, 0x7e, 0x16, 0xfc, 0xa1, 0x70, 0xb5, 0x24, 0x0d,
- 0x7d, 0xa2, 0xc1, 0xbc, 0xe7, 0xeb, 0x96, 0xa1, 0xf7, 0x6d, 0x0b, 0xdf, 0xb4, 0x7a, 0x2e, 0xf6,
- 0xbc, 0x9b, 0xd6, 0xb6, 0x5d, 0xad, 0x50, 0x3d, 0x17, 0x12, 0x89, 0x55, 0x45, 0xda, 0xbc, 0x30,
- 0x1a, 0xd6, 0x6a, 0x4a, 0x29, 0x92, 0x66, 0xb5, 0x22, 0xb4, 0x0f, 0xb3, 0xe1, 0x47, 0xfa, 0xbe,
- 0x6f, 0xf6, 0x4d, 0x4f, 0xf7, 0x4d, 0xdb, 0xaa, 0x9e, 0xa6, 0xfa, 0xcf, 0x27, 0xf3, 0xd3, 0x18,
- 0x61, 0xf3, 0xfc, 0x68, 0x58, 0x3b, 0xa7, 0x90, 0x20, 0xe9, 0x56, 0xa9, 0x88, 0x9d, 0xb8, 0xe9,
- 0x62, 0x42, 0x88, 0x8d, 0xea, 0xec, 0x64, 0x27, 0x46, 0x44, 0xa2, 0x13, 0x23, 0xa0, 0xca, 0x89,
- 0x11, 0x92, 0x68, 0x72, 0x74, 0xd7, 0x37, 0x89, 0xda, 0x0d, 0xdd, 0xdd, 0xc5, 0x6e, 0x75, 0x4e,
- 0xa5, 0x69, 0x53, 0x26, 0x62, 0x9a, 0x12, 0x9c, 0xb2, 0xa6, 0x04, 0x12, 0x7d, 0xae, 0x81, 0x6c,
- 0x9a, 0x69, 0x5b, 0x2d, 0xf2, 0xd1, 0xf6, 0xc8, 0xeb, 0xcd, 0x53, 0xa5, 0xcf, 0x3f, 0xe2, 0xf5,
- 0x44, 0xf2, 0xe6, 0xf3, 0xa3, 0x61, 0xed, 0xc2, 0x44, 0x69, 0x92, 0x21, 0x93, 0x95, 0xa2, 0x07,
- 0x50, 0x22, 0x48, 0x4c, 0xcb, 0x1f, 0xa3, 0xba, 0x40, 0x6d, 0x38, 0x3b, 0x6e, 0x03, 0x27, 0x68,
- 0x9e, 0x1d, 0x0d, 0x6b, 0xf3, 0x02, 0x87, 0xa4, 0x47, 0x14, 0x85, 0x3e, 0xd3, 0x80, 0x04, 0xba,
- 0xea, 0x4d, 0xcf, 0x50, 0x2d, 0xcf, 0x8d, 0x69, 0x51, 0xbd, 0xe6, 0x73, 0xa3, 0x61, 0x6d, 0x59,
- 0x2d, 0x47, 0xd2, 0x3d, 0x41, 0x57, 0x1c, 0x47, 0xd1, 0x47, 0xa2, 0x5a, 0x9d, 0x1c, 0x47, 0x11,
- 0x91, 0x18, 0x47, 0x11, 0x50, 0x15, 0x47, 0x11, 0x92, 0x27, 0x83, 0xf7, 0xf4, 0xbe, 0x69, 0xd0,
- 0x62, 0xea, 0xec, 0x84, 0x64, 0x10, 0x51, 0x44, 0xc9, 0x20, 0x82, 0x8c, 0x25, 0x83, 0x98, 0x36,
- 0x0f, 0x59, 0x2a, 0xa2, 0xfe, 0xc7, 0x1c, 0xcc, 0x2a, 0xb6, 0x1a, 0xc2, 0x30, 0x1d, 0xee, 0xa3,
- 0xb6, 0x49, 0x92, 0x44, 0x5a, 0xb5, 0xca, 0xb7, 0x82, 0x0e, 0x76, 0x2d, 0xec, 0x63, 0x2f, 0x94,
- 0x41, 0xb3, 0x04, 0xb5, 0xc4, 0x15, 0x20, 0x42, 0x6d, 0x37, 0x25, 0xc2, 0xd1, 0x8f, 0x35, 0xa8,
- 0x0e, 0xf4, 0xfd, 0x76, 0x08, 0xf4, 0xda, 0xdb, 0xb6, 0xdb, 0x76, 0xb0, 0x6b, 0xda, 0x06, 0xad,
- 0x64, 0x4b, 0x57, 0xfe, 0xed, 0xd0, 0xbc, 0xd0, 0xd8, 0xd0, 0xf7, 0x43, 0xb0, 0xf7, 0x8e, 0xed,
- 0x6e, 0x52, 0xf6, 0x35, 0xcb, 0x77, 0x0f, 0x58, 0xc2, 0x1a, 0xa8, 0xf0, 0x82, 0x4d, 0xf3, 0x4a,
- 0x02, 0xf4, 0xff, 0x1a, 0x2c, 0xf8, 0xb6, 0xaf, 0xf7, 0xdb, 0xdd, 0x60, 0x10, 0xf4, 0x75, 0xdf,
- 0xdc, 0xc3, 0xed, 0xc0, 0xd3, 0x7b, 0x98, 0x97, 0xcd, 0x6f, 0x1e, 0x6e, 0xda, 0x3d, 0xc2, 0x7f,
- 0x35, 0x62, 0xbf, 0x4f, 0xb8, 0x99, 0x65, 0xf5, 0xd1, 0xb0, 0xb6, 0xe4, 0x2b, 0xd0, 0x82, 0x61,
- 0x73, 0x2a, 0x3c, 0x7a, 0x01, 0x72, 0xa4, 0xad, 0x30, 0x0d, 0x5a, 0x1d, 0xf1, 0x16, 0xe4, 0xa1,
- 0xdd, 0x91, 0x1a, 0x83, 0x2c, 0x05, 0x10, 0x5a, 0x37, 0xb0, 0x08, 0x6d, 0x3e, 0xa6, 0x75, 0x03,
- 0x4b, 0xa6, 0xa5, 0x80, 0xc5, 0x2f, 0x34, 0x58, 0x9c, 0xbc, 0x94, 0xe8, 0x02, 0xa4, 0x77, 0xf1,
- 0x01, 0x6f, 0x7b, 0x4e, 0x8f, 0x86, 0xb5, 0xe9, 0x5d, 0x7c, 0x20, 0x48, 0x21, 0x58, 0xf4, 0x1f,
- 0x90, 0xdd, 0xd3, 0xfb, 0x01, 0xe6, 0x55, 0x75, 0xa3, 0xc1, 0x3a, 0xb6, 0x86, 0xd8, 0xb1, 0x35,
- 0x9c, 0xdd, 0x1e, 0x01, 0x34, 0x42, 0xaf, 0x37, 0xde, 0x0d, 0x74, 0xcb, 0x37, 0xfd, 0x03, 0x66,
- 0x1e, 0x15, 0x20, 0x9a, 0x47, 0x01, 0x6f, 0xa4, 0x5e, 0xd3, 0x16, 0x7f, 0xa2, 0xc1, 0xd9, 0x89,
- 0x4b, 0xfa, 0x7d, 0xb0, 0x70, 0x3d, 0x53, 0xd0, 0x2a, 0xa9, 0xf5, 0x4c, 0x21, 0x55, 0x49, 0xd7,
- 0x7f, 0x9e, 0x87, 0x62, 0xd4, 0xa0, 0xa0, 0x1b, 0x50, 0x31, 0xb0, 0x11, 0x38, 0x7d, 0xb3, 0x4b,
- 0x63, 0x83, 0x38, 0x85, 0x75, 0x84, 0x34, 0x3b, 0x48, 0x38, 0xc9, 0x3d, 0x33, 0x09, 0x14, 0xba,
- 0x02, 0x05, 0x5e, 0x88, 0x1f, 0xd0, 0x7d, 0x39, 0xdd, 0x5c, 0x18, 0x0d, 0x6b, 0x28, 0x84, 0x09,
- 0xac, 0x11, 0x1d, 0x6a, 0x01, 0xb0, 0xce, 0x76, 0x03, 0xfb, 0x3a, 0x6f, 0x09, 0xaa, 0x72, 0xfc,
- 0xde, 0x8d, 0xf0, 0xac, 0x47, 0x8d, 0xe9, 0xc5, 0x1e, 0x35, 0x86, 0xa2, 0xf7, 0x01, 0x06, 0xba,
- 0x69, 0x31, 0x3e, 0x5e, 0xff, 0xd7, 0x27, 0x65, 0x88, 0x8d, 0x88, 0x92, 0x49, 0x8f, 0x39, 0x45,
- 0xe9, 0x31, 0x14, 0xdd, 0x85, 0x3c, 0xef, 0xc5, 0xab, 0x39, 0xba, 0xdd, 0x96, 0x26, 0x89, 0xe6,
- 0x62, 0x69, 0x37, 0xc9, 0x59, 0xc4, 0x6e, 0x92, 0x83, 0xc8, 0xb2, 0xf5, 0xcd, 0x6d, 0xec, 0x9b,
- 0x03, 0x4c, 0x77, 0x03, 0x5f, 0xb6, 0x10, 0x26, 0x2e, 0x5b, 0x08, 0x43, 0xaf, 0x01, 0xe8, 0xfe,
- 0x86, 0xed, 0xf9, 0x77, 0xad, 0x2e, 0xa6, 0x15, 0x7d, 0x81, 0x99, 0x1f, 0x43, 0x45, 0xf3, 0x63,
- 0x28, 0x7a, 0x13, 0x4a, 0x0e, 0xff, 0x82, 0x74, 0xfa, 0x98, 0x56, 0xec, 0x05, 0xf6, 0xc1, 0x13,
- 0xc0, 0x02, 0xaf, 0x48, 0x8d, 0xae, 0xc3, 0x4c, 0xd7, 0xb6, 0xba, 0x81, 0xeb, 0x62, 0xab, 0x7b,
- 0xb0, 0xa5, 0x6f, 0x63, 0x5a, 0x9d, 0x17, 0x58, 0xa8, 0x24, 0x50, 0x62, 0xa8, 0x24, 0x50, 0xe8,
- 0x55, 0x28, 0x46, 0x93, 0x0d, 0x5a, 0x80, 0x17, 0x79, 0xa3, 0x1c, 0x02, 0x05, 0xe6, 0x98, 0x92,
- 0x18, 0x6f, 0x7a, 0xd7, 0x78, 0xd0, 0x61, 0x5a, 0x54, 0x73, 0xe3, 0x05, 0xb0, 0x68, 0xbc, 0x00,
- 0x16, 0xf2, 0x53, 0xf9, 0xd0, 0xfc, 0xf4, 0x5f, 0x30, 0x8f, 0xf7, 0x49, 0xbe, 0x1f, 0x60, 0xcb,
- 0xd7, 0xfb, 0x9b, 0xae, 0xc9, 0xbe, 0x0c, 0xd5, 0x19, 0x55, 0x51, 0xba, 0xa6, 0x22, 0x65, 0x39,
- 0x5e, 0x29, 0x45, 0xcc, 0xf1, 0x4a, 0x82, 0x68, 0xbb, 0x4e, 0x57, 0xca, 0xf5, 0x5b, 0x30, 0xaf,
- 0x54, 0x40, 0x02, 0xa7, 0x63, 0x1a, 0xf4, 0x99, 0x26, 0x17, 0x8d, 0x05, 0x4e, 0x08, 0x13, 0x03,
- 0x27, 0x84, 0xd5, 0x7f, 0xab, 0xc1, 0x9c, 0x2a, 0xf8, 0x13, 0x1b, 0x51, 0x7b, 0x22, 0x1b, 0xf1,
- 0x3d, 0x28, 0x38, 0xb6, 0xd1, 0xf6, 0x1c, 0xdc, 0xe5, 0x69, 0x2d, 0xb1, 0x0d, 0x37, 0x6d, 0x63,
- 0xcb, 0xc1, 0xdd, 0x7f, 0x37, 0xfd, 0x9d, 0xd5, 0x3d, 0xdb, 0x34, 0x6e, 0x9b, 0x1e, 0xdf, 0x2f,
- 0x0e, 0xc3, 0x48, 0xb5, 0x42, 0x9e, 0x03, 0x9b, 0x05, 0xc8, 0x31, 0x2d, 0xf5, 0xdf, 0xa5, 0xa1,
- 0x92, 0xdc, 0x70, 0x7f, 0x4f, 0xaf, 0x82, 0x1e, 0x40, 0xde, 0x64, 0xad, 0x08, 0x2f, 0x65, 0xfe,
- 0x49, 0x48, 0xfc, 0x8d, 0x78, 0x2e, 0xd9, 0xd8, 0x7b, 0xb9, 0xc1, 0x7b, 0x16, 0xba, 0x04, 0x54,
- 0x32, 0xe7, 0x94, 0x25, 0x73, 0x20, 0x6a, 0x41, 0xde, 0xc3, 0xee, 0x1e, 0x09, 0x0e, 0x96, 0x56,
- 0x6b, 0xa2, 0xe4, 0xae, 0xed, 0x62, 0x22, 0x73, 0x8b, 0x91, 0xc4, 0x32, 0x39, 0x8f, 0x2c, 0x93,
- 0x03, 0xd1, 0x7b, 0x50, 0xec, 0xda, 0xd6, 0xb6, 0xd9, 0xdb, 0xd0, 0x1d, 0x9e, 0x58, 0xcf, 0xa9,
- 0xa4, 0x5e, 0x0d, 0x89, 0xf8, 0x78, 0x25, 0x7c, 0x4c, 0x8c, 0x57, 0x22, 0xaa, 0xd8, 0xa1, 0x7f,
- 0xcd, 0x00, 0xc4, 0xce, 0x41, 0xaf, 0x43, 0x09, 0xef, 0xe3, 0x6e, 0xe0, 0xdb, 0x74, 0xe4, 0xa8,
- 0xc5, 0x93, 0xca, 0x10, 0x2c, 0xed, 0x5e, 0x88, 0xa1, 0x24, 0xc5, 0x58, 0xfa, 0x00, 0x7b, 0x8e,
- 0xde, 0x0d, 0x47, 0x9c, 0xd4, 0x98, 0x08, 0x28, 0xa6, 0x98, 0x08, 0x88, 0xfe, 0x19, 0x32, 0x74,
- 0x28, 0xca, 0xa6, 0x9b, 0x68, 0x34, 0xac, 0x95, 0x2d, 0x79, 0x1c, 0x4a, 0xf1, 0xe8, 0x6d, 0x98,
- 0xde, 0x8d, 0x02, 0x8f, 0xd8, 0x96, 0xa1, 0x0c, 0xb4, 0xc6, 0x8c, 0x11, 0x92, 0x75, 0x53, 0x22,
- 0x1c, 0x6d, 0x43, 0x49, 0xb7, 0x2c, 0xdb, 0xa7, 0x5f, 0xcf, 0x70, 0xe2, 0x79, 0x69, 0x52, 0x98,
- 0x36, 0x56, 0x63, 0x5a, 0x56, 0xa8, 0xd1, 0xb4, 0x27, 0x48, 0x10, 0xd3, 0x9e, 0x00, 0x46, 0x2d,
- 0xc8, 0xf5, 0xf5, 0x0e, 0xee, 0x87, 0x9f, 0xab, 0xe7, 0x26, 0xaa, 0xb8, 0x4d, 0xc9, 0x98, 0x74,
- 0x3a, 0x57, 0x65, 0x7c, 0xe2, 0x5c, 0x95, 0x41, 0x16, 0xb7, 0xa1, 0x92, 0xb4, 0xe7, 0x68, 0x55,
- 0xce, 0x25, 0xb1, 0xca, 0x29, 0x1e, 0x5a, 0x57, 0xe9, 0x50, 0x12, 0x8c, 0x3a, 0x09, 0x15, 0xf5,
- 0x2f, 0x35, 0x98, 0x53, 0xed, 0x5d, 0xb4, 0x21, 0xec, 0x78, 0x8d, 0x4f, 0x6f, 0x14, 0xa1, 0xce,
- 0x79, 0x27, 0x6c, 0xf5, 0x78, 0xa3, 0x37, 0xa1, 0x6c, 0xd9, 0x06, 0x6e, 0xeb, 0x44, 0x41, 0xdf,
- 0xf4, 0xfc, 0x6a, 0x8a, 0x4e, 0xc4, 0xe9, 0xd4, 0x87, 0x60, 0x56, 0x43, 0x84, 0xc0, 0x3d, 0x2d,
- 0x21, 0xea, 0x1f, 0xc1, 0x4c, 0x62, 0x26, 0x2b, 0xd5, 0x5c, 0xa9, 0x23, 0xd6, 0x5c, 0xf1, 0x87,
- 0x30, 0x7d, 0xd8, 0x87, 0x90, 0x7d, 0x88, 0xea, 0xff, 0x9b, 0x82, 0x92, 0xd0, 0x20, 0xa3, 0x87,
- 0x30, 0xc3, 0x3f, 0xca, 0xa6, 0xd5, 0x63, 0x8d, 0x58, 0x8a, 0x7f, 0x18, 0xc7, 0x0e, 0x2c, 0xd6,
- 0xed, 0xce, 0x56, 0x44, 0x4b, 0x3f, 0x8c, 0x74, 0x98, 0xe6, 0x49, 0x30, 0x41, 0x71, 0x59, 0xc6,
- 0xa0, 0x07, 0xb0, 0x10, 0x38, 0xa4, 0x3d, 0x6c, 0x7b, 0x7c, 0xf4, 0xdf, 0xb6, 0x82, 0x41, 0x07,
- 0xbb, 0xd4, 0xfa, 0x2c, 0x6b, 0x58, 0x18, 0x45, 0x78, 0x36, 0x70, 0x87, 0xe2, 0xc5, 0x86, 0x45,
- 0x85, 0x17, 0xd6, 0x21, 0x73, 0xc4, 0x75, 0xb8, 0x01, 0x68, 0x7c, 0x28, 0x2e, 0xf9, 0x40, 0x3b,
- 0x9a, 0x0f, 0xea, 0xfb, 0x50, 0x49, 0x8e, 0xba, 0x9f, 0x92, 0x2f, 0x77, 0xa1, 0x18, 0x0d, 0xaa,
- 0xd1, 0x8b, 0x90, 0x73, 0xb1, 0xee, 0xd9, 0x16, 0xdf, 0x2d, 0x74, 0xdb, 0x33, 0x88, 0xb8, 0xed,
- 0x19, 0xe4, 0x31, 0x94, 0xdd, 0x83, 0x29, 0xb6, 0x48, 0xef, 0x98, 0x7d, 0x1f, 0xbb, 0xe8, 0x1a,
- 0xe4, 0x3c, 0x5f, 0xf7, 0xb1, 0x57, 0xd5, 0x96, 0xd3, 0x17, 0xcb, 0x57, 0x16, 0xc6, 0xa7, 0xd0,
- 0x04, 0xcd, 0xec, 0x60, 0x94, 0xa2, 0x1d, 0x0c, 0x52, 0xff, 0x1f, 0x0d, 0xa6, 0xc4, 0x61, 0xfb,
- 0x93, 0x11, 0x7b, 0xbc, 0xc5, 0xa8, 0x5b, 0xa1, 0x0d, 0x7c, 0xcc, 0x7e, 0xd2, 0x4b, 0xf9, 0xa5,
- 0xc6, 0xd6, 0x32, 0x9a, 0xcb, 0xf6, 0xe2, 0x59, 0x08, 0xd9, 0x28, 0x1e, 0x4d, 0x28, 0x47, 0x9d,
- 0x85, 0xd0, 0xb4, 0x23, 0xb1, 0x8b, 0x69, 0x47, 0x42, 0x3c, 0x86, 0xad, 0x5f, 0x64, 0xa9, 0xad,
- 0xf1, 0xd4, 0x3d, 0xf1, 0x1d, 0x4f, 0x1f, 0xe3, 0x3b, 0xfe, 0x12, 0xe4, 0x69, 0xe2, 0x8c, 0xb6,
- 0x29, 0x5d, 0x58, 0x02, 0x92, 0x4f, 0x1c, 0x19, 0xe4, 0x11, 0xe9, 0x22, 0xfb, 0x1d, 0xd3, 0x45,
- 0x1b, 0xce, 0xee, 0xe8, 0x5e, 0x3b, 0x4c, 0x70, 0x46, 0x5b, 0xf7, 0xdb, 0xd1, 0x7e, 0xcd, 0xd1,
- 0x56, 0x84, 0xce, 0xf1, 0x76, 0x74, 0x6f, 0x2b, 0xa4, 0x59, 0xf5, 0x37, 0xc7, 0x77, 0xef, 0x82,
- 0x9a, 0x02, 0xdd, 0x87, 0x79, 0xb5, 0xf0, 0x3c, 0xb5, 0x9c, 0x8e, 0x99, 0xbd, 0x47, 0x4a, 0x9e,
- 0x55, 0xa0, 0xd1, 0xa7, 0x1a, 0x54, 0xc9, 0x97, 0xcc, 0xc5, 0x1f, 0x06, 0xa6, 0x8b, 0x49, 0x17,
- 0xe1, 0xb5, 0xed, 0x3d, 0xec, 0xf6, 0xf5, 0x03, 0x7e, 0x62, 0x73, 0x7e, 0x3c, 0x6d, 0x6f, 0xda,
- 0x46, 0x4b, 0x60, 0x60, 0xaf, 0xe6, 0xc8, 0xc0, 0xbb, 0x4c, 0x88, 0xf8, 0x6a, 0x6a, 0x0a, 0x21,
- 0x84, 0xe0, 0x18, 0xb3, 0xa1, 0xd2, 0x61, 0xb3, 0x21, 0x52, 0xad, 0x39, 0xb6, 0xdd, 0xa7, 0x9d,
- 0x20, 0xaf, 0xd6, 0xc8, 0xb3, 0x58, 0xad, 0x91, 0x67, 0x71, 0xfc, 0xb1, 0x9e, 0x29, 0x14, 0x2a,
- 0xc5, 0xfa, 0xd7, 0x1a, 0x94, 0xe5, 0x43, 0x9e, 0xf1, 0x0d, 0x95, 0x3e, 0xf1, 0x0d, 0x95, 0x39,
- 0xc6, 0x6a, 0x64, 0x0f, 0x5b, 0x0d, 0x69, 0xc8, 0xf3, 0x27, 0x0d, 0xa6, 0xa5, 0xf3, 0xa5, 0x1f,
- 0xd6, 0xeb, 0xfd, 0x28, 0x05, 0x0b, 0x6a, 0x53, 0x4f, 0xa4, 0xfd, 0xbb, 0x01, 0xa4, 0x90, 0xbb,
- 0x19, 0x17, 0x3a, 0xf3, 0x63, 0xdd, 0x1f, 0x5d, 0xa6, 0xb0, 0x0a, 0x1c, 0x3b, 0x7a, 0x0a, 0xd9,
- 0xd1, 0x03, 0x28, 0x99, 0xc2, 0x21, 0x57, 0x5a, 0x75, 0x16, 0x21, 0x1e, 0x6d, 0xb1, 0xe9, 0xc6,
- 0x84, 0x03, 0x2d, 0x51, 0x54, 0x33, 0x07, 0x19, 0x52, 0x89, 0xd5, 0xf7, 0x20, 0xcf, 0xcd, 0x41,
- 0xaf, 0x40, 0x91, 0xe6, 0x4e, 0xda, 0xd1, 0xb0, 0xb2, 0x99, 0x96, 0x14, 0x04, 0x98, 0xb8, 0xe4,
- 0x51, 0x08, 0x61, 0xe8, 0x5f, 0x01, 0x48, 0xba, 0xe0, 0x59, 0x33, 0x45, 0x73, 0x0f, 0xed, 0x9c,
- 0x1c, 0xdb, 0x18, 0x4b, 0x95, 0xc5, 0x08, 0x58, 0xff, 0x45, 0x0a, 0x4a, 0xe2, 0xb1, 0xda, 0x63,
- 0x29, 0xff, 0x18, 0xc2, 0xae, 0xb6, 0xad, 0x1b, 0x06, 0xf9, 0x8b, 0xc3, 0x0f, 0xdb, 0xca, 0xc4,
- 0x45, 0x0a, 0xff, 0x5f, 0x0d, 0x39, 0x58, 0x0f, 0x43, 0xaf, 0x0e, 0x98, 0x09, 0x94, 0xa0, 0xb5,
- 0x92, 0xc4, 0x2d, 0xee, 0xc2, 0xbc, 0x52, 0x94, 0xd8, 0x79, 0x64, 0x9f, 0x54, 0xe7, 0xf1, 0xd3,
- 0x2c, 0xcc, 0x2b, 0x8f, 0x33, 0x13, 0x11, 0x9c, 0x7e, 0x22, 0x11, 0xfc, 0x7f, 0x9a, 0x6a, 0x65,
- 0xd9, 0x59, 0xc6, 0xeb, 0x47, 0x38, 0x63, 0x7d, 0x52, 0x6b, 0x2c, 0x87, 0x45, 0xf6, 0xb1, 0x62,
- 0x32, 0x77, 0xd4, 0x98, 0x44, 0x97, 0x59, 0x13, 0x47, 0x75, 0xb1, 0x93, 0x86, 0x70, 0x87, 0x26,
- 0x54, 0xe5, 0x39, 0x88, 0xf4, 0xf5, 0x21, 0x07, 0x1b, 0x1d, 0x14, 0xe2, 0xbe, 0x9e, 0xd3, 0x24,
- 0xa7, 0x07, 0x53, 0x22, 0x5c, 0xc8, 0x7e, 0xc5, 0x63, 0x64, 0x3f, 0x38, 0xf4, 0x18, 0xe4, 0x69,
- 0xc6, 0xa6, 0x94, 0x6a, 0x87, 0x1a, 0xcc, 0x24, 0x6e, 0x11, 0xfc, 0xb0, 0xbe, 0x25, 0x9f, 0x68,
- 0x50, 0x8c, 0x2e, 0xa9, 0xa0, 0x55, 0xc8, 0x61, 0x76, 0xd1, 0x81, 0xa5, 0x9d, 0xd9, 0xc4, 0xac,
- 0x97, 0xe0, 0xf8, 0xb5, 0xb3, 0xc4, 0xdd, 0x86, 0x16, 0x67, 0x7c, 0x8c, 0x82, 0xf9, 0x97, 0x5a,
- 0x58, 0x30, 0x8f, 0x59, 0x91, 0xfe, 0xee, 0x56, 0x9c, 0xdc, 0xd2, 0xfd, 0xba, 0x08, 0x59, 0x6a,
- 0x0b, 0x69, 0x5e, 0x7d, 0xec, 0x0e, 0x4c, 0x4b, 0xef, 0xd3, 0x50, 0x2c, 0xb0, 0x5d, 0x1d, 0xc2,
- 0xc4, 0x5d, 0x1d, 0xc2, 0xd0, 0x0e, 0xcc, 0xc4, 0x23, 0x31, 0x2a, 0x46, 0x7d, 0xeb, 0xed, 0x96,
- 0x4c, 0xc4, 0x4e, 0x1b, 0x12, 0x9c, 0xf2, 0xb1, 0x75, 0x02, 0x89, 0x0c, 0x28, 0x77, 0x6d, 0xcb,
- 0xd7, 0x4d, 0x0b, 0xbb, 0x4c, 0x51, 0x5a, 0x75, 0xeb, 0xe7, 0xaa, 0x44, 0xc3, 0x06, 0x15, 0x32,
- 0x9f, 0x7c, 0xeb, 0x47, 0xc6, 0xa1, 0x0f, 0x60, 0x3a, 0x6c, 0x5c, 0x98, 0x92, 0x8c, 0xea, 0xd6,
- 0xcf, 0x9a, 0x48, 0xc2, 0x36, 0x83, 0xc4, 0x25, 0xdf, 0xfa, 0x91, 0x50, 0xa8, 0x0f, 0x15, 0xc7,
- 0x36, 0xee, 0x5b, 0xbc, 0x5c, 0xd7, 0x3b, 0x7d, 0xcc, 0xe7, 0xb0, 0x4b, 0x63, 0x05, 0x89, 0x44,
- 0xc5, 0x12, 0x75, 0x92, 0x57, 0xbe, 0x47, 0x97, 0xc4, 0xa2, 0xf7, 0x61, 0xaa, 0x4f, 0xfa, 0xb7,
- 0xb5, 0x7d, 0xc7, 0x74, 0xb1, 0xa1, 0xbe, 0xf5, 0x76, 0x5b, 0xa0, 0x60, 0x69, 0x52, 0xe4, 0x91,
- 0x0f, 0xfb, 0x45, 0x0c, 0xf1, 0xfe, 0x40, 0xdf, 0x6f, 0x05, 0x96, 0xb7, 0xb6, 0xcf, 0x6f, 0x30,
- 0xe5, 0x55, 0xde, 0xdf, 0x90, 0x89, 0x98, 0xf7, 0x13, 0x9c, 0xb2, 0xf7, 0x13, 0x48, 0x74, 0x9b,
- 0x7e, 0x05, 0x98, 0x4b, 0xd8, 0xed, 0xb7, 0x85, 0xb1, 0xd5, 0x62, 0xde, 0x60, 0x03, 0x17, 0xfe,
- 0x24, 0x09, 0x8d, 0x24, 0x70, 0x1f, 0xd0, 0xd7, 0x6e, 0x61, 0x3f, 0x70, 0x2d, 0x6c, 0xf0, 0x36,
- 0x6a, 0xdc, 0x07, 0x12, 0x55, 0xe4, 0x03, 0x09, 0x3a, 0xe6, 0x03, 0x09, 0x8b, 0x3e, 0x86, 0xb9,
- 0xc4, 0x5d, 0x1e, 0xf6, 0x1e, 0x25, 0xd5, 0x21, 0xc4, 0xba, 0x82, 0x92, 0x75, 0xbc, 0x2a, 0x19,
- 0x92, 0x66, 0xa5, 0x16, 0xa2, 0xbd, 0xa7, 0x5b, 0xbd, 0x75, 0xbb, 0x23, 0xc7, 0xdc, 0x94, 0x4a,
- 0xfb, 0x75, 0x05, 0x25, 0xd3, 0xae, 0x92, 0x21, 0x6b, 0x57, 0x51, 0x44, 0xf7, 0x76, 0x48, 0x11,
- 0x13, 0xdd, 0x6f, 0x53, 0xdd, 0xdb, 0x61, 0x04, 0xc2, 0xbd, 0x1d, 0x06, 0x50, 0xdc, 0xdb, 0xe1,
- 0x94, 0x85, 0x70, 0x58, 0x53, 0x7f, 0x17, 0x66, 0x12, 0xe9, 0x05, 0xbd, 0x05, 0xd1, 0x6d, 0x90,
- 0x7b, 0x07, 0x4e, 0x58, 0xbb, 0x4a, 0xb7, 0x47, 0x08, 0x5c, 0x75, 0x7b, 0x84, 0xc0, 0xeb, 0x9f,
- 0x67, 0xa0, 0x10, 0x46, 0xd4, 0x89, 0x74, 0x23, 0x2b, 0x90, 0x1f, 0x60, 0x8f, 0xde, 0xf8, 0x48,
- 0xc5, 0x45, 0x0d, 0x07, 0x89, 0x45, 0x0d, 0x07, 0xc9, 0x35, 0x57, 0xfa, 0xb1, 0x6a, 0xae, 0xcc,
- 0x91, 0x6b, 0x2e, 0x4c, 0x0f, 0x89, 0x85, 0xbc, 0x18, 0x1e, 0x6e, 0x3c, 0x3a, 0xd9, 0x86, 0x47,
- 0xc8, 0x22, 0x63, 0xe2, 0x08, 0x59, 0x44, 0xa1, 0x5d, 0x38, 0x2d, 0x1c, 0xc0, 0xf0, 0xd1, 0x1b,
- 0xc9, 0x50, 0xe5, 0xc9, 0x27, 0xf2, 0x2d, 0x4a, 0xc5, 0xf6, 0xe1, 0x6e, 0x02, 0x2a, 0x16, 0xad,
- 0x49, 0x1c, 0x09, 0x09, 0x03, 0x77, 0x82, 0xde, 0x06, 0x5f, 0xf6, 0x7c, 0x1c, 0x12, 0x22, 0x5c,
- 0x0c, 0x09, 0x11, 0x5e, 0xff, 0x4b, 0x0a, 0xca, 0xf2, 0xfb, 0x9e, 0x48, 0x60, 0xbc, 0x02, 0x45,
- 0xbc, 0x6f, 0xfa, 0xed, 0xae, 0x6d, 0x60, 0xde, 0xb9, 0x51, 0x3f, 0x13, 0xe0, 0x55, 0xdb, 0x90,
- 0xfc, 0x1c, 0xc2, 0xc4, 0x68, 0x4a, 0x1f, 0x29, 0x9a, 0xe2, 0x49, 0x67, 0xe6, 0x08, 0x93, 0x4e,
- 0xa5, 0x9f, 0x8a, 0x27, 0xe3, 0xa7, 0xfa, 0x57, 0x29, 0xa8, 0x24, 0xd3, 0xee, 0xf7, 0x63, 0x0b,
- 0xca, 0xbb, 0x29, 0x7d, 0xe4, 0xdd, 0xf4, 0x36, 0x4c, 0x93, 0xca, 0x4c, 0xf7, 0x7d, 0x7e, 0x41,
- 0x34, 0x43, 0x8b, 0x2b, 0x96, 0x8d, 0x02, 0x6b, 0x35, 0x84, 0x4b, 0xd9, 0x48, 0x80, 0x8f, 0x85,
- 0x6e, 0xf6, 0x98, 0xa1, 0xfb, 0x69, 0x0a, 0xa6, 0x37, 0x6d, 0xe3, 0x1e, 0x2b, 0xda, 0xfc, 0xef,
- 0xcb, 0x7a, 0x3e, 0xcd, 0x94, 0x56, 0x9f, 0x81, 0x69, 0xa9, 0x6a, 0xab, 0x7f, 0xc6, 0xe2, 0x4c,
- 0xfe, 0x5c, 0xfd, 0xe3, 0xad, 0x4b, 0x19, 0xa6, 0xc4, 0xf2, 0xaf, 0xde, 0x84, 0x99, 0x44, 0xb5,
- 0x26, 0xbe, 0x80, 0x76, 0x94, 0x17, 0xa8, 0x5f, 0x83, 0x39, 0x55, 0x19, 0x23, 0x64, 0x1d, 0xed,
- 0x08, 0xa7, 0x33, 0xd7, 0x61, 0x4e, 0x55, 0x8e, 0x1c, 0xdf, 0x9c, 0xb7, 0xf8, 0xc9, 0x27, 0x2b,
- 0x1c, 0x8e, 0xcf, 0xff, 0xfb, 0xa8, 0x7b, 0x8e, 0x2f, 0x63, 0xbf, 0x03, 0x15, 0x27, 0x7c, 0x68,
- 0xf3, 0x1e, 0x8d, 0x6d, 0x4b, 0xda, 0x71, 0x44, 0xb8, 0xf5, 0x44, 0xb3, 0x56, 0x96, 0x31, 0xb2,
- 0x1c, 0xde, 0xbf, 0xe5, 0x14, 0x72, 0x5a, 0x89, 0x46, 0xae, 0x2c, 0x63, 0x84, 0xa5, 0xcd, 0x1f,
- 0xbe, 0xb4, 0xb4, 0xff, 0xcb, 0x92, 0xa6, 0x79, 0x26, 0x71, 0x59, 0x1c, 0x5d, 0x86, 0x02, 0xfd,
- 0x25, 0x57, 0xdc, 0xf9, 0xd2, 0xd5, 0xa1, 0x30, 0xc9, 0x80, 0x3c, 0x07, 0xa1, 0x57, 0xa1, 0x18,
- 0xdd, 0x1f, 0xe7, 0x67, 0x9e, 0x2c, 0xee, 0x42, 0xa0, 0x14, 0x77, 0x21, 0x90, 0x37, 0xcd, 0xff,
- 0x0d, 0x67, 0x27, 0xde, 0x1c, 0x3f, 0x4e, 0x0f, 0x2e, 0x74, 0xbf, 0x99, 0x63, 0x75, 0xbf, 0xfb,
- 0xb0, 0xa0, 0xbe, 0xd0, 0x2d, 0x68, 0x4f, 0x1d, 0xaa, 0x3d, 0x5e, 0xfd, 0xf4, 0x11, 0x57, 0x3f,
- 0x55, 0xdf, 0xa5, 0xe3, 0x82, 0xe8, 0xe2, 0x34, 0xba, 0x04, 0x59, 0xc7, 0xb6, 0xfb, 0x1e, 0xbf,
- 0x54, 0x40, 0xd5, 0x51, 0x80, 0xa8, 0x8e, 0x02, 0x1e, 0x63, 0x38, 0x11, 0x84, 0x11, 0x1c, 0x5f,
- 0x03, 0x7f, 0x0a, 0xab, 0xfb, 0xc2, 0x65, 0x28, 0x84, 0x07, 0xb7, 0x08, 0x20, 0xf7, 0xee, 0xfd,
- 0xb5, 0xfb, 0x6b, 0xd7, 0x2a, 0xa7, 0x50, 0x09, 0xf2, 0x9b, 0x6b, 0x77, 0xae, 0xdd, 0xbc, 0x73,
- 0xbd, 0xa2, 0x91, 0x87, 0xd6, 0xfd, 0x3b, 0x77, 0xc8, 0x43, 0xea, 0x85, 0xdb, 0xe2, 0x65, 0x30,
- 0x5e, 0xb9, 0x4d, 0x41, 0x61, 0xd5, 0x71, 0x68, 0x0a, 0x61, 0xbc, 0x6b, 0x7b, 0x26, 0xd9, 0xc9,
- 0x15, 0x0d, 0xe5, 0x21, 0x7d, 0xf7, 0xee, 0x46, 0x25, 0x85, 0xe6, 0xa0, 0x72, 0x0d, 0xeb, 0x46,
- 0xdf, 0xb4, 0x70, 0x98, 0xb7, 0x2a, 0xe9, 0xe6, 0xc3, 0xdf, 0x7c, 0xb3, 0xa4, 0x7d, 0xf5, 0xcd,
- 0x92, 0xf6, 0xe7, 0x6f, 0x96, 0xb4, 0xcf, 0xbf, 0x5d, 0x3a, 0xf5, 0xd5, 0xb7, 0x4b, 0xa7, 0xfe,
- 0xf0, 0xed, 0xd2, 0xa9, 0xff, 0xbc, 0xdc, 0x33, 0xfd, 0x9d, 0xa0, 0xd3, 0xe8, 0xda, 0x03, 0xfe,
- 0x93, 0x54, 0xc7, 0xb5, 0x49, 0x82, 0xe0, 0x4f, 0x2b, 0xc9, 0xdf, 0xaa, 0xfe, 0x2c, 0x75, 0x6e,
- 0x95, 0x3e, 0x6e, 0x32, 0xba, 0xc6, 0x4d, 0xbb, 0xc1, 0x00, 0xf4, 0xd7, 0x89, 0x5e, 0x27, 0x47,
- 0x7f, 0x85, 0xf8, 0xca, 0xdf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x44, 0xa5, 0x08, 0xe6, 0x3a,
- 0x00, 0x00,
+ // 3720 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, 0x1f, 0xf4, 0xd5, 0x87, 0x69, 0x25, 0x16, 0x65, 0x3a, 0x2f, 0xb1,
+ 0x83, 0x84, 0x72, 0x9c, 0x97, 0x87, 0x7c, 0x3c, 0x24, 0x10, 0x6d, 0xc5, 0xb6, 0x6c, 0xd9, 0x0a,
+ 0x65, 0xe5, 0xf9, 0x3d, 0x04, 0x60, 0x86, 0x9c, 0x2b, 0x6a, 0x2c, 0x72, 0x66, 0x32, 0x1f, 0x8a,
+ 0x04, 0x04, 0xef, 0x25, 0x0f, 0x69, 0xd7, 0xd9, 0x14, 0x28, 0xb2, 0x69, 0x36, 0x5d, 0xb4, 0x68,
+ 0x97, 0xed, 0xb6, 0xdb, 0x2e, 0x8a, 0x22, 0x9b, 0x02, 0x5d, 0x34, 0x44, 0x91, 0xa0, 0x1b, 0x2e,
+ 0xfa, 0x1b, 0x8a, 0xfb, 0x31, 0x33, 0xf7, 0x0e, 0x2f, 0x2d, 0xc9, 0xb1, 0x0c, 0x37, 0x5d, 0x49,
+ 0x73, 0x3e, 0xef, 0x9c, 0x73, 0xee, 0x99, 0x73, 0xce, 0xbd, 0x84, 0x73, 0xce, 0x6e, 0x77, 0x59,
+ 0x77, 0xfb, 0xba, 0xa1, 0xe3, 0x3d, 0x6c, 0xf9, 0xde, 0x32, 0xfb, 0x53, 0x77, 0x5c, 0xdb, 0xb7,
+ 0xd1, 0x84, 0x88, 0x5a, 0xa8, 0xed, 0xbe, 0xee, 0xd5, 0x4d, 0x7b, 0x59, 0x77, 0xcc, 0xe5, 0x8e,
+ 0xed, 0xe2, 0xe5, 0xbd, 0x57, 0x96, 0xbb, 0xd8, 0xc2, 0xae, 0xee, 0x63, 0x83, 0x71, 0x2c, 0x5c,
+ 0x14, 0x68, 0x2c, 0xec, 0x7f, 0x6c, 0xbb, 0xbb, 0xa6, 0xd5, 0x55, 0x51, 0x56, 0xbb, 0xb6, 0xdd,
+ 0xed, 0xe1, 0x65, 0xfa, 0xd4, 0x0e, 0xb6, 0x97, 0x7d, 0xb3, 0x8f, 0x3d, 0x5f, 0xef, 0x3b, 0x9c,
+ 0xe0, 0xdf, 0x63, 0x51, 0x7d, 0xbd, 0xb3, 0x63, 0x5a, 0xd8, 0x3d, 0x58, 0xa6, 0xeb, 0x75, 0xcc,
+ 0x65, 0x17, 0x7b, 0x76, 0xe0, 0x76, 0xf0, 0x88, 0xd8, 0x37, 0x4d, 0xcb, 0xc7, 0xae, 0xa5, 0xf7,
+ 0x96, 0xbd, 0xce, 0x0e, 0x36, 0x82, 0x1e, 0x76, 0xe3, 0xff, 0xec, 0xf6, 0x03, 0xdc, 0xf1, 0xbd,
+ 0x11, 0x00, 0xe3, 0xad, 0x7d, 0x33, 0x07, 0x93, 0xab, 0xe4, 0x5d, 0x37, 0xf1, 0x47, 0x01, 0xb6,
+ 0x3a, 0x18, 0x5d, 0x82, 0xec, 0x47, 0x01, 0x0e, 0x70, 0x45, 0x5b, 0xd2, 0x2e, 0x16, 0x1b, 0x33,
+ 0xc3, 0x41, 0x75, 0x9a, 0x02, 0x5e, 0xb2, 0xfb, 0xa6, 0x8f, 0xfb, 0x8e, 0x7f, 0xd0, 0x64, 0x14,
+ 0xe8, 0x4d, 0x98, 0x78, 0x60, 0xb7, 0x5b, 0x1e, 0xf6, 0x5b, 0x96, 0xde, 0xc7, 0x95, 0x14, 0xe5,
+ 0xa8, 0x0c, 0x07, 0xd5, 0xd9, 0x07, 0x76, 0x7b, 0x13, 0xfb, 0x77, 0xf4, 0xbe, 0xc8, 0x06, 0x31,
+ 0x14, 0xbd, 0x0c, 0xf9, 0xc0, 0xc3, 0x6e, 0xcb, 0x34, 0x2a, 0x69, 0xca, 0x36, 0x3b, 0x1c, 0x54,
+ 0xcb, 0x04, 0x74, 0xd3, 0x10, 0x58, 0x72, 0x0c, 0x82, 0x5e, 0x82, 0x5c, 0xd7, 0xb5, 0x03, 0xc7,
+ 0xab, 0x64, 0x96, 0xd2, 0x21, 0x35, 0x83, 0x88, 0xd4, 0x0c, 0x82, 0xee, 0x42, 0x8e, 0x39, 0xb0,
+ 0x92, 0x5d, 0x4a, 0x5f, 0x2c, 0x5d, 0x39, 0x5f, 0x17, 0xbd, 0x5a, 0x97, 0x5e, 0x98, 0x3d, 0x31,
+ 0x81, 0x0c, 0x2f, 0x0a, 0xe4, 0x71, 0xf0, 0xdb, 0x19, 0xc8, 0x52, 0x3a, 0x74, 0x0b, 0xf2, 0x1d,
+ 0x17, 0x13, 0xeb, 0x57, 0xd0, 0x92, 0x76, 0xb1, 0x74, 0x65, 0xa1, 0xce, 0xbc, 0x5a, 0x0f, 0xbd,
+ 0x5a, 0xbf, 0x17, 0x7a, 0xb5, 0x31, 0x37, 0x1c, 0x54, 0x4f, 0x73, 0x72, 0x41, 0x6a, 0x28, 0x01,
+ 0x6d, 0x40, 0xd1, 0x0b, 0xda, 0x7d, 0xd3, 0x5f, 0xb3, 0xdb, 0xd4, 0xde, 0xa5, 0x2b, 0x67, 0xe4,
+ 0xa5, 0x6e, 0x86, 0xe8, 0xc6, 0x99, 0xe1, 0xa0, 0x3a, 0x13, 0x51, 0xc7, 0xd2, 0x6e, 0x9c, 0x6a,
+ 0xc6, 0x42, 0xd0, 0x0e, 0x4c, 0xbb, 0xd8, 0x71, 0x4d, 0xdb, 0x35, 0x7d, 0xd3, 0xc3, 0x44, 0x6e,
+ 0x8a, 0xca, 0x3d, 0x27, 0xcb, 0x6d, 0xca, 0x44, 0x8d, 0x73, 0xc3, 0x41, 0xf5, 0x6c, 0x82, 0x53,
+ 0xd2, 0x91, 0x14, 0x8b, 0x7c, 0x40, 0x09, 0xd0, 0x26, 0xf6, 0xa9, 0x2f, 0x4b, 0x57, 0x96, 0x1e,
+ 0xaa, 0x6c, 0x13, 0xfb, 0x8d, 0xa5, 0xe1, 0xa0, 0xfa, 0xec, 0x28, 0xbf, 0xa4, 0x52, 0x21, 0x1f,
+ 0xf5, 0xa0, 0x2c, 0x42, 0x0d, 0xf2, 0x82, 0x19, 0xaa, 0x73, 0x71, 0xbc, 0x4e, 0x42, 0xd5, 0x58,
+ 0x1c, 0x0e, 0xaa, 0x0b, 0x49, 0x5e, 0x49, 0xdf, 0x88, 0x64, 0xe2, 0x9f, 0x8e, 0x6e, 0x75, 0x70,
+ 0x8f, 0xa8, 0xc9, 0xaa, 0xfc, 0x73, 0x35, 0x44, 0x33, 0xff, 0x44, 0xd4, 0xb2, 0x7f, 0x22, 0x30,
+ 0xfa, 0x00, 0x26, 0xa2, 0x07, 0x62, 0xaf, 0x1c, 0x8f, 0x21, 0xb5, 0x50, 0x62, 0xa9, 0x85, 0xe1,
+ 0xa0, 0x3a, 0x2f, 0xf2, 0x48, 0xa2, 0x25, 0x69, 0xb1, 0xf4, 0x1e, 0xb3, 0x4c, 0x7e, 0xbc, 0x74,
+ 0x46, 0x21, 0x4a, 0xef, 0x8d, 0x5a, 0x44, 0x92, 0x46, 0xa4, 0x93, 0x0d, 0x1c, 0x74, 0x3a, 0x18,
+ 0x1b, 0xd8, 0xa8, 0x14, 0x54, 0xd2, 0xd7, 0x04, 0x0a, 0x26, 0x5d, 0xe4, 0x91, 0xa5, 0x8b, 0x18,
+ 0x62, 0xeb, 0x07, 0x76, 0x7b, 0xd5, 0x75, 0x6d, 0xd7, 0xab, 0x14, 0x55, 0xb6, 0x5e, 0x0b, 0xd1,
+ 0xcc, 0xd6, 0x11, 0xb5, 0x6c, 0xeb, 0x08, 0xcc, 0xd7, 0xdb, 0x0c, 0xac, 0xdb, 0x58, 0xf7, 0xb0,
+ 0x51, 0x81, 0x31, 0xeb, 0x8d, 0x28, 0xa2, 0xf5, 0x46, 0x90, 0x91, 0xf5, 0x46, 0x18, 0x64, 0xc0,
+ 0x14, 0x7b, 0x5e, 0xf1, 0x3c, 0xb3, 0x6b, 0x61, 0xa3, 0x52, 0xa2, 0xf2, 0x9f, 0x55, 0xc9, 0x0f,
+ 0x69, 0x1a, 0xcf, 0x0e, 0x07, 0xd5, 0x8a, 0xcc, 0x27, 0xe9, 0x48, 0xc8, 0x44, 0x1f, 0xc2, 0x24,
+ 0x83, 0x34, 0x03, 0xcb, 0x32, 0xad, 0x6e, 0x65, 0x82, 0x2a, 0x79, 0x46, 0xa5, 0x84, 0x93, 0x34,
+ 0x9e, 0x19, 0x0e, 0xaa, 0x67, 0x24, 0x2e, 0x49, 0x85, 0x2c, 0x90, 0x64, 0x0c, 0x06, 0x88, 0x1d,
+ 0x3b, 0xa9, 0xca, 0x18, 0x6b, 0x32, 0x11, 0xcb, 0x18, 0x09, 0x4e, 0x39, 0x63, 0x24, 0x90, 0xb1,
+ 0x3f, 0xb8, 0x93, 0xa7, 0xc6, 0xfb, 0x83, 0xfb, 0x59, 0xf0, 0x87, 0xc2, 0xd5, 0x92, 0x34, 0xf4,
+ 0xa9, 0x06, 0x73, 0x9e, 0xaf, 0x5b, 0x86, 0xde, 0xb3, 0x2d, 0x7c, 0xd3, 0xea, 0xba, 0xd8, 0xf3,
+ 0x6e, 0x5a, 0xdb, 0x76, 0xa5, 0x4c, 0xf5, 0x5c, 0x48, 0x24, 0x56, 0x15, 0x69, 0xe3, 0xc2, 0x70,
+ 0x50, 0xad, 0x2a, 0xa5, 0x48, 0x9a, 0xd5, 0x8a, 0xd0, 0x3e, 0xcc, 0x84, 0x1f, 0xe9, 0x2d, 0xdf,
+ 0xec, 0x99, 0x9e, 0xee, 0x9b, 0xb6, 0x55, 0x39, 0x4d, 0xf5, 0x9f, 0x4f, 0xe6, 0xa7, 0x11, 0xc2,
+ 0xc6, 0xf9, 0xe1, 0xa0, 0x7a, 0x4e, 0x21, 0x41, 0xd2, 0xad, 0x52, 0x11, 0x3b, 0x71, 0xc3, 0xc5,
+ 0x84, 0x10, 0x1b, 0x95, 0x99, 0xf1, 0x4e, 0x8c, 0x88, 0x44, 0x27, 0x46, 0x40, 0x95, 0x13, 0x23,
+ 0x24, 0xd1, 0xe4, 0xe8, 0xae, 0x6f, 0x12, 0xb5, 0xeb, 0xba, 0xbb, 0x8b, 0xdd, 0xca, 0xac, 0x4a,
+ 0xd3, 0x86, 0x4c, 0xc4, 0x34, 0x25, 0x38, 0x65, 0x4d, 0x09, 0x24, 0xfa, 0x42, 0x03, 0x79, 0x69,
+ 0xa6, 0x6d, 0x35, 0xc9, 0x47, 0xdb, 0x23, 0xaf, 0x37, 0x47, 0x95, 0xbe, 0xf0, 0x90, 0xd7, 0x13,
+ 0xc9, 0x1b, 0x2f, 0x0c, 0x07, 0xd5, 0x0b, 0x63, 0xa5, 0x49, 0x0b, 0x19, 0xaf, 0x14, 0xdd, 0x87,
+ 0x12, 0x41, 0x62, 0x5a, 0xfe, 0x18, 0x95, 0x79, 0xba, 0x86, 0xb3, 0xa3, 0x6b, 0xe0, 0x04, 0x8d,
+ 0xb3, 0xc3, 0x41, 0x75, 0x4e, 0xe0, 0x90, 0xf4, 0x88, 0xa2, 0xd0, 0xe7, 0x1a, 0x90, 0x40, 0x57,
+ 0xbd, 0xe9, 0x19, 0xaa, 0xe5, 0xb9, 0x11, 0x2d, 0xaa, 0xd7, 0x7c, 0x6e, 0x38, 0xa8, 0x2e, 0xa9,
+ 0xe5, 0x48, 0xba, 0xc7, 0xe8, 0x8a, 0xe3, 0x28, 0xfa, 0x48, 0x54, 0x2a, 0xe3, 0xe3, 0x28, 0x22,
+ 0x12, 0xe3, 0x28, 0x02, 0xaa, 0xe2, 0x28, 0x42, 0xf2, 0x64, 0xf0, 0xbe, 0xde, 0x33, 0x0d, 0x5a,
+ 0x4c, 0x9d, 0x1d, 0x93, 0x0c, 0x22, 0x8a, 0x28, 0x19, 0x44, 0x90, 0x91, 0x64, 0x10, 0xd3, 0xe6,
+ 0x21, 0x4b, 0x45, 0xd4, 0xbe, 0x2c, 0xc2, 0x8c, 0x62, 0xab, 0x21, 0x0c, 0x93, 0xe1, 0x3e, 0x6a,
+ 0x99, 0x24, 0x49, 0xa4, 0x55, 0x56, 0xbe, 0x15, 0xb4, 0xb1, 0x6b, 0x61, 0x1f, 0x7b, 0xa1, 0x0c,
+ 0x9a, 0x25, 0xe8, 0x4a, 0x5c, 0x01, 0x22, 0xd4, 0x76, 0x13, 0x22, 0x1c, 0x7d, 0xa9, 0x41, 0xa5,
+ 0xaf, 0xef, 0xb7, 0x42, 0xa0, 0xd7, 0xda, 0xb6, 0xdd, 0x96, 0x83, 0x5d, 0xd3, 0x36, 0x68, 0x25,
+ 0x5b, 0xba, 0xf2, 0x9f, 0x87, 0xe6, 0x85, 0xfa, 0xba, 0xbe, 0x1f, 0x82, 0xbd, 0x77, 0x6d, 0x77,
+ 0x83, 0xb2, 0xaf, 0x5a, 0xbe, 0x7b, 0xc0, 0x12, 0x56, 0x5f, 0x85, 0x17, 0xd6, 0x34, 0xa7, 0x24,
+ 0x40, 0x3f, 0xd1, 0x60, 0xde, 0xb7, 0x7d, 0xbd, 0xd7, 0xea, 0x04, 0xfd, 0xa0, 0xa7, 0xfb, 0xe6,
+ 0x1e, 0x6e, 0x05, 0x9e, 0xde, 0xc5, 0xbc, 0x6c, 0x7e, 0xeb, 0xf0, 0xa5, 0xdd, 0x23, 0xfc, 0x57,
+ 0x23, 0xf6, 0x2d, 0xc2, 0xcd, 0x56, 0x56, 0x1b, 0x0e, 0xaa, 0x8b, 0xbe, 0x02, 0x2d, 0x2c, 0x6c,
+ 0x56, 0x85, 0x47, 0x2f, 0x42, 0x8e, 0xb4, 0x15, 0xa6, 0x41, 0xab, 0x23, 0xde, 0x82, 0x3c, 0xb0,
+ 0xdb, 0x52, 0x63, 0x90, 0xa5, 0x00, 0x42, 0xeb, 0x06, 0x16, 0xa1, 0xcd, 0xc7, 0xb4, 0x6e, 0x60,
+ 0xc9, 0xb4, 0x14, 0x40, 0x9d, 0xa1, 0xef, 0x75, 0xd5, 0xce, 0x28, 0x1c, 0xd5, 0x19, 0x2b, 0x7b,
+ 0xdd, 0x87, 0x3a, 0x43, 0x57, 0xe1, 0x45, 0x67, 0x28, 0x09, 0x16, 0xbe, 0xd2, 0x60, 0x61, 0xbc,
+ 0x9f, 0xd1, 0x05, 0x48, 0xef, 0xe2, 0x03, 0xde, 0x93, 0x9d, 0x1e, 0x0e, 0xaa, 0x93, 0xbb, 0xf8,
+ 0x40, 0x90, 0x4a, 0xb0, 0xe8, 0xbf, 0x21, 0xbb, 0xa7, 0xf7, 0x02, 0xcc, 0x4b, 0xfe, 0x7a, 0x9d,
+ 0xb5, 0x93, 0x75, 0xb1, 0x9d, 0xac, 0x3b, 0xbb, 0x5d, 0x02, 0xa8, 0x87, 0x56, 0xa8, 0xbf, 0x17,
+ 0xe8, 0x96, 0x6f, 0xfa, 0x07, 0xcc, 0x76, 0x54, 0x80, 0x68, 0x3b, 0x0a, 0x78, 0x33, 0xf5, 0xba,
+ 0xb6, 0xf0, 0x33, 0x0d, 0xce, 0x8e, 0xf5, 0xf7, 0x53, 0xb1, 0x42, 0x62, 0xc4, 0xf1, 0xfe, 0x79,
+ 0x1a, 0x96, 0xb8, 0x96, 0x29, 0x68, 0xe5, 0xd4, 0x5a, 0xa6, 0x90, 0x2a, 0xa7, 0x6b, 0xbf, 0xca,
+ 0x43, 0x31, 0x6a, 0xf0, 0xd0, 0x0d, 0x28, 0x1b, 0xd8, 0x08, 0x9c, 0x9e, 0xd9, 0xa1, 0x91, 0x46,
+ 0x82, 0x9a, 0x75, 0xd4, 0x34, 0xbb, 0x4a, 0x38, 0x29, 0xbc, 0xa7, 0x13, 0x28, 0x74, 0x05, 0x0a,
+ 0xbc, 0x91, 0x39, 0xa0, 0x79, 0x6d, 0xb2, 0x31, 0x3f, 0x1c, 0x54, 0x51, 0x08, 0x13, 0x58, 0x23,
+ 0x3a, 0xd4, 0x04, 0x60, 0x93, 0x81, 0x75, 0xec, 0xeb, 0xbc, 0xa5, 0xaa, 0xc8, 0xbb, 0xe1, 0x6e,
+ 0x84, 0x67, 0x3d, 0x7e, 0x4c, 0x2f, 0xf6, 0xf8, 0x31, 0x14, 0x7d, 0x00, 0xd0, 0xd7, 0x4d, 0x8b,
+ 0xf1, 0xf1, 0xfe, 0xa9, 0x36, 0x2e, 0xc3, 0xae, 0x47, 0x94, 0x4c, 0x7a, 0xcc, 0x29, 0x4a, 0x8f,
+ 0xa1, 0xe8, 0x2e, 0xe4, 0xf9, 0x2c, 0xa3, 0x92, 0xa3, 0x9b, 0x77, 0x71, 0x9c, 0x68, 0x2e, 0x96,
+ 0x76, 0xe3, 0x9c, 0x45, 0xec, 0xc6, 0x39, 0x88, 0x98, 0xad, 0x67, 0x6e, 0x63, 0xdf, 0xec, 0x63,
+ 0x9a, 0x4d, 0xb8, 0xd9, 0x42, 0x98, 0x68, 0xb6, 0x10, 0x86, 0x5e, 0x07, 0xd0, 0xfd, 0x75, 0xdb,
+ 0xf3, 0xef, 0x5a, 0x1d, 0x4c, 0x3b, 0xa2, 0x02, 0x5b, 0x7e, 0x0c, 0x15, 0x97, 0x1f, 0x43, 0xd1,
+ 0x5b, 0x50, 0x72, 0xf8, 0x17, 0xb8, 0xdd, 0xc3, 0xb4, 0xe3, 0x29, 0xb0, 0x82, 0x41, 0x00, 0x0b,
+ 0xbc, 0x22, 0x35, 0xba, 0x0e, 0xd3, 0x1d, 0xdb, 0xea, 0x04, 0xae, 0x8b, 0xad, 0xce, 0xc1, 0xa6,
+ 0xbe, 0x8d, 0x69, 0x77, 0x53, 0x60, 0xa1, 0x92, 0x40, 0x89, 0xa1, 0x92, 0x40, 0xa1, 0xd7, 0xa0,
+ 0x18, 0x4d, 0x86, 0x68, 0x03, 0x53, 0xe4, 0x83, 0x86, 0x10, 0x28, 0x30, 0xc7, 0x94, 0x64, 0xf1,
+ 0xa6, 0x77, 0x8d, 0x07, 0x1d, 0xa6, 0x4d, 0x09, 0x5f, 0xbc, 0x00, 0x16, 0x17, 0x2f, 0x80, 0x85,
+ 0xfc, 0x3e, 0x75, 0x68, 0x7e, 0xff, 0x5f, 0x98, 0xc3, 0xfb, 0x24, 0x45, 0xf7, 0xb1, 0xe5, 0xeb,
+ 0xbd, 0x0d, 0xd7, 0x64, 0x5f, 0xd6, 0xca, 0xb4, 0xaa, 0xa8, 0x5f, 0x55, 0x91, 0xb2, 0xb4, 0xac,
+ 0x94, 0x22, 0xa6, 0x65, 0x25, 0x41, 0xb4, 0x5d, 0x27, 0xcb, 0x53, 0xb5, 0x5b, 0x30, 0xa7, 0x54,
+ 0x40, 0x02, 0xa7, 0x6d, 0x1a, 0xf4, 0x99, 0x26, 0x17, 0x8d, 0x05, 0x4e, 0x08, 0x13, 0x03, 0x27,
+ 0x84, 0xd5, 0xfe, 0xa0, 0xc1, 0xac, 0x2a, 0xf8, 0x13, 0x1b, 0x51, 0x7b, 0x2c, 0x1b, 0xf1, 0x7d,
+ 0x28, 0x38, 0xb6, 0xd1, 0xf2, 0x1c, 0xdc, 0xe1, 0x69, 0x2d, 0xb1, 0x0d, 0x37, 0x6c, 0x63, 0xd3,
+ 0xc1, 0x9d, 0xff, 0x32, 0xfd, 0x9d, 0x95, 0x3d, 0xdb, 0x34, 0x6e, 0x9b, 0x1e, 0xdf, 0x2f, 0x0e,
+ 0xc3, 0x48, 0xb5, 0x56, 0x9e, 0x03, 0x1b, 0x05, 0xc8, 0x31, 0x2d, 0xb5, 0x3f, 0xa6, 0xa1, 0x9c,
+ 0xdc, 0x70, 0xff, 0x4c, 0xaf, 0x82, 0xee, 0x43, 0xde, 0x64, 0xad, 0x1c, 0x2f, 0x05, 0xff, 0x4d,
+ 0x48, 0xfc, 0xf5, 0x78, 0xae, 0x5b, 0xdf, 0x7b, 0xa5, 0xce, 0x7b, 0x3e, 0x6a, 0x02, 0x2a, 0x99,
+ 0x73, 0xca, 0x92, 0x39, 0x10, 0x35, 0x21, 0xef, 0x61, 0x77, 0x8f, 0x04, 0x07, 0x4b, 0xab, 0x55,
+ 0x51, 0x72, 0xc7, 0x76, 0x31, 0x91, 0xb9, 0xc9, 0x48, 0x62, 0x99, 0x9c, 0x47, 0x96, 0xc9, 0x81,
+ 0xe8, 0x7d, 0x28, 0x76, 0x6c, 0x6b, 0xdb, 0xec, 0xae, 0xeb, 0x0e, 0x4f, 0xac, 0xe7, 0x54, 0x52,
+ 0xaf, 0x86, 0x44, 0x7c, 0x3c, 0x15, 0x3e, 0x26, 0xc6, 0x53, 0x11, 0x55, 0xec, 0xd0, 0xbf, 0x67,
+ 0x00, 0x62, 0xe7, 0xa0, 0x37, 0xa0, 0x84, 0xf7, 0x71, 0x27, 0xf0, 0x6d, 0x3a, 0xb2, 0xd5, 0xe2,
+ 0x49, 0x6f, 0x08, 0x96, 0x76, 0x2f, 0xc4, 0x50, 0x92, 0x62, 0x2c, 0xbd, 0x8f, 0x3d, 0x47, 0xef,
+ 0x84, 0x23, 0x62, 0xba, 0x98, 0x08, 0x28, 0xa6, 0x98, 0x08, 0x88, 0x9e, 0x87, 0x0c, 0x1d, 0x2a,
+ 0xb3, 0xe9, 0x30, 0x1a, 0x0e, 0xaa, 0x53, 0x96, 0x3c, 0x4e, 0xa6, 0x78, 0xf4, 0x0e, 0x4c, 0xee,
+ 0x46, 0x81, 0x47, 0xd6, 0x96, 0xa1, 0x0c, 0xb4, 0x46, 0x8f, 0x11, 0xd2, 0xea, 0x26, 0x44, 0x38,
+ 0xda, 0x86, 0x92, 0x6e, 0x59, 0xb6, 0x4f, 0xbf, 0x9e, 0xe1, 0xc4, 0xf8, 0xd2, 0xb8, 0x30, 0xad,
+ 0xaf, 0xc4, 0xb4, 0xac, 0xea, 0xa3, 0x69, 0x4f, 0x90, 0x20, 0xa6, 0x3d, 0x01, 0x8c, 0x9a, 0x90,
+ 0xeb, 0xe9, 0x6d, 0xdc, 0x0b, 0x3f, 0x57, 0xcf, 0x8d, 0x55, 0x71, 0x9b, 0x92, 0x31, 0xe9, 0x74,
+ 0x2e, 0xcd, 0xf8, 0xc4, 0xb9, 0x34, 0x83, 0x2c, 0x6c, 0x43, 0x39, 0xb9, 0x9e, 0xa3, 0x55, 0x39,
+ 0x97, 0xc4, 0x2a, 0xa7, 0x78, 0x68, 0x61, 0xa5, 0x43, 0x49, 0x58, 0xd4, 0x49, 0xa8, 0xa8, 0xfd,
+ 0x42, 0x83, 0x59, 0xd5, 0xde, 0x45, 0xeb, 0xc2, 0x8e, 0xd7, 0xf8, 0xf4, 0x4b, 0x11, 0xea, 0x9c,
+ 0x77, 0xcc, 0x56, 0x8f, 0x37, 0x7a, 0x03, 0xa6, 0x2c, 0xdb, 0xc0, 0x2d, 0x9d, 0x28, 0xe8, 0x99,
+ 0x9e, 0x5f, 0x49, 0xd1, 0x13, 0x05, 0x3a, 0x35, 0x23, 0x98, 0x95, 0x10, 0x21, 0x70, 0x4f, 0x4a,
+ 0x88, 0xda, 0xc7, 0x30, 0x9d, 0x98, 0x69, 0x4b, 0x35, 0x57, 0xea, 0x88, 0x35, 0x57, 0xfc, 0x21,
+ 0x4c, 0x1f, 0xf6, 0x21, 0x64, 0x1f, 0xa2, 0xda, 0x8f, 0x52, 0x50, 0x12, 0x06, 0x0c, 0xe8, 0x01,
+ 0x4c, 0xf3, 0x8f, 0xb2, 0x69, 0x75, 0x59, 0x23, 0x9b, 0xe2, 0x1f, 0xc6, 0x91, 0x03, 0x9f, 0x35,
+ 0xbb, 0xbd, 0x19, 0xd1, 0xd2, 0x0f, 0x23, 0x1d, 0x46, 0x7a, 0x12, 0x4c, 0x50, 0x3c, 0x25, 0x63,
+ 0xd0, 0x7d, 0x98, 0x0f, 0x1c, 0xd2, 0x5e, 0xb7, 0x3c, 0x7e, 0x74, 0xd2, 0xb2, 0x82, 0x7e, 0x1b,
+ 0xbb, 0x74, 0xf5, 0x59, 0xd6, 0xf0, 0x31, 0x8a, 0xf0, 0x6c, 0xe5, 0x0e, 0xc5, 0x8b, 0x0d, 0x9f,
+ 0x0a, 0x2f, 0xd8, 0x21, 0x73, 0x44, 0x3b, 0xdc, 0x00, 0x34, 0x7a, 0xa8, 0x20, 0xf9, 0x40, 0x3b,
+ 0x9a, 0x0f, 0x6a, 0xfb, 0x50, 0x4e, 0x1e, 0x15, 0x3c, 0x21, 0x5f, 0xee, 0x42, 0x31, 0x1a, 0xf4,
+ 0xa3, 0x97, 0x20, 0xe7, 0x62, 0xdd, 0xb3, 0x2d, 0xbe, 0x5b, 0xe8, 0xb6, 0x67, 0x10, 0x71, 0xdb,
+ 0x33, 0xc8, 0x23, 0x28, 0xbb, 0x07, 0x13, 0xcc, 0x48, 0xef, 0x9a, 0x3d, 0x1f, 0xbb, 0xe8, 0x1a,
+ 0xe4, 0x3c, 0x5f, 0xf7, 0xb1, 0x57, 0xd1, 0x96, 0xd2, 0x17, 0xa7, 0xae, 0xcc, 0x8f, 0x4e, 0xf1,
+ 0x09, 0x9a, 0xad, 0x83, 0x51, 0x8a, 0xeb, 0x60, 0x90, 0xda, 0xff, 0x6b, 0x30, 0x21, 0x1e, 0x56,
+ 0x3c, 0x1e, 0xb1, 0xc7, 0x33, 0x06, 0x49, 0x1c, 0x13, 0xe2, 0x99, 0xc6, 0xc9, 0xd9, 0x92, 0x7c,
+ 0x05, 0xd9, 0x89, 0x48, 0x2b, 0xf0, 0xb0, 0xcb, 0xa3, 0x95, 0x7e, 0x05, 0x19, 0x78, 0xcb, 0x93,
+ 0xa2, 0x1d, 0x62, 0x28, 0x77, 0x03, 0x59, 0xab, 0x78, 0x42, 0x82, 0xba, 0xf1, 0x1c, 0x8a, 0x6c,
+ 0x32, 0x8f, 0x26, 0xa3, 0xa3, 0xce, 0xa1, 0x68, 0xca, 0x92, 0xd8, 0xc5, 0x94, 0x25, 0x21, 0x1e,
+ 0x21, 0x64, 0xbe, 0xca, 0xd2, 0xb5, 0xc6, 0x27, 0x1e, 0x89, 0x1a, 0x20, 0x7d, 0x8c, 0x1a, 0xe0,
+ 0x65, 0xc8, 0xd3, 0xa4, 0x1b, 0x6d, 0x71, 0xea, 0x13, 0x02, 0x92, 0x4f, 0x7b, 0x19, 0xe4, 0x21,
+ 0xa9, 0x26, 0xfb, 0x3d, 0x53, 0x4d, 0x0b, 0xce, 0xee, 0xe8, 0x5e, 0x2b, 0x4c, 0x8e, 0x46, 0x4b,
+ 0xf7, 0x5b, 0xd1, 0x5e, 0xcf, 0xd1, 0x36, 0x86, 0xce, 0x50, 0x77, 0x74, 0x6f, 0x33, 0xa4, 0x59,
+ 0xf1, 0x37, 0x46, 0x77, 0xfe, 0xbc, 0x9a, 0x02, 0x6d, 0xc1, 0x9c, 0x5a, 0x78, 0x9e, 0xae, 0x9c,
+ 0x8e, 0xf8, 0xbd, 0x87, 0x4a, 0x9e, 0x51, 0xa0, 0xd1, 0x67, 0x1a, 0x54, 0xc8, 0x57, 0xd0, 0xc5,
+ 0x1f, 0x05, 0xa6, 0x8b, 0x49, 0x07, 0xe2, 0xb5, 0xec, 0x3d, 0xec, 0xf6, 0xf4, 0x03, 0x7e, 0x5a,
+ 0x76, 0x7e, 0x34, 0xe5, 0x6f, 0xd8, 0x46, 0x53, 0x60, 0x60, 0xaf, 0xe6, 0xc8, 0xc0, 0xbb, 0x4c,
+ 0x88, 0xf8, 0x6a, 0x6a, 0x0a, 0x21, 0x84, 0xe0, 0x18, 0x73, 0xb9, 0xd2, 0xa1, 0x73, 0xb9, 0xe7,
+ 0x21, 0xe3, 0xd8, 0x76, 0x8f, 0x76, 0x91, 0xbc, 0xd2, 0x23, 0xcf, 0x62, 0xa5, 0x47, 0x9e, 0xc5,
+ 0xd1, 0xc9, 0x5a, 0xa6, 0x50, 0x28, 0x17, 0x6b, 0xdf, 0x68, 0x30, 0x25, 0x1f, 0xb0, 0x8d, 0x6e,
+ 0xa8, 0xf4, 0x89, 0x6f, 0xa8, 0xcc, 0x31, 0xac, 0x91, 0x3d, 0xcc, 0x1a, 0xd2, 0x80, 0xe8, 0x2f,
+ 0x1a, 0x4c, 0x4a, 0x67, 0x7b, 0x3f, 0xac, 0xd7, 0xfb, 0x69, 0x0a, 0xe6, 0xd5, 0x4b, 0x3d, 0x91,
+ 0xd6, 0xf1, 0x06, 0x90, 0x22, 0xf0, 0x66, 0x5c, 0x24, 0xcd, 0x8d, 0x74, 0x8e, 0xd4, 0x4c, 0x61,
+ 0x05, 0x39, 0x72, 0xec, 0x17, 0xb2, 0xa3, 0xfb, 0x50, 0x32, 0x85, 0x03, 0xc6, 0xb4, 0xea, 0x1c,
+ 0x48, 0x3c, 0x56, 0x64, 0x93, 0x91, 0x31, 0x87, 0x89, 0xa2, 0xa8, 0x46, 0x0e, 0x32, 0xa4, 0x8a,
+ 0xab, 0xed, 0x41, 0x9e, 0x2f, 0x07, 0xbd, 0x0a, 0x45, 0x9a, 0x3b, 0x69, 0x37, 0xc4, 0x4a, 0x6e,
+ 0x5a, 0x8e, 0x10, 0x60, 0xe2, 0x82, 0x4d, 0x21, 0x84, 0xa1, 0xff, 0x00, 0x20, 0xe9, 0x82, 0x67,
+ 0xcd, 0x14, 0xcd, 0x3d, 0xb4, 0xeb, 0x72, 0x6c, 0x63, 0x24, 0x55, 0x16, 0x23, 0x60, 0xed, 0xd7,
+ 0x29, 0x28, 0x89, 0x47, 0x9a, 0x8f, 0xa4, 0xfc, 0x13, 0x08, 0x3b, 0xe2, 0x96, 0x6e, 0x18, 0xe4,
+ 0x2f, 0x0e, 0x3f, 0x6c, 0xcb, 0x63, 0x8d, 0x14, 0xfe, 0xbf, 0x12, 0x72, 0xb0, 0xfe, 0x87, 0x5e,
+ 0xdb, 0x30, 0x13, 0x28, 0x41, 0x6b, 0x39, 0x89, 0x5b, 0xd8, 0x85, 0x39, 0xa5, 0x28, 0xb1, 0x6b,
+ 0xc9, 0x3e, 0xae, 0xae, 0xe5, 0xe7, 0x59, 0x98, 0x53, 0x1e, 0x25, 0x27, 0x22, 0x38, 0xfd, 0x58,
+ 0x22, 0xf8, 0xc7, 0x9a, 0xca, 0xb2, 0xec, 0x1c, 0xe9, 0x8d, 0x23, 0x9c, 0x6f, 0x3f, 0x2e, 0x1b,
+ 0xcb, 0x61, 0x91, 0x7d, 0xa4, 0x98, 0xcc, 0x1d, 0x35, 0x26, 0xd1, 0x65, 0xd6, 0x00, 0x52, 0x5d,
+ 0xec, 0x94, 0x27, 0xdc, 0xa1, 0x09, 0x55, 0x79, 0x0e, 0x42, 0xef, 0xc0, 0x64, 0xc8, 0xc1, 0xc6,
+ 0x0e, 0x85, 0x78, 0x26, 0xc0, 0x69, 0x92, 0x93, 0x87, 0x09, 0x11, 0x2e, 0x64, 0xbf, 0xe2, 0x31,
+ 0xb2, 0x1f, 0x1c, 0x96, 0xfd, 0x9e, 0x68, 0x6c, 0x4a, 0xa9, 0x76, 0xa0, 0xc1, 0x74, 0xe2, 0x06,
+ 0xc7, 0x0f, 0xeb, 0x5b, 0xf2, 0xa9, 0x06, 0xc5, 0xe8, 0x82, 0x10, 0x5a, 0x81, 0x1c, 0x66, 0x97,
+ 0x4c, 0x58, 0xda, 0x99, 0x49, 0xcc, 0x89, 0x09, 0x8e, 0x5f, 0xf9, 0x4b, 0xdc, 0x2b, 0x69, 0x72,
+ 0xc6, 0x47, 0x28, 0x98, 0x7f, 0xa3, 0x85, 0x05, 0xf3, 0xc8, 0x2a, 0xd2, 0xdf, 0x7f, 0x15, 0x27,
+ 0x67, 0xba, 0xdf, 0x15, 0x21, 0x4b, 0xd7, 0x42, 0x1a, 0x5f, 0x1f, 0xbb, 0x7d, 0xd3, 0xd2, 0x7b,
+ 0x34, 0x14, 0x0b, 0x6c, 0x57, 0x87, 0x30, 0x71, 0x57, 0x87, 0x30, 0xb4, 0x03, 0xd3, 0xf1, 0x38,
+ 0x8d, 0x8a, 0x51, 0xdf, 0x38, 0xbc, 0x25, 0x13, 0xb1, 0x93, 0x8a, 0x04, 0xa7, 0x7c, 0x65, 0x20,
+ 0x81, 0x44, 0x06, 0x4c, 0x75, 0x6c, 0xcb, 0xd7, 0x4d, 0x0b, 0xbb, 0x4c, 0x51, 0x5a, 0x75, 0xe3,
+ 0xea, 0xaa, 0x44, 0xc3, 0x86, 0x1c, 0x32, 0x9f, 0x7c, 0xe3, 0x4a, 0xc6, 0xa1, 0x0f, 0x61, 0x32,
+ 0x6c, 0x5c, 0x98, 0x92, 0x8c, 0xea, 0xc6, 0xd5, 0xaa, 0x48, 0xc2, 0x36, 0x83, 0xc4, 0x25, 0xdf,
+ 0xb8, 0x92, 0x50, 0xa8, 0x07, 0x65, 0xc7, 0x36, 0xb6, 0x2c, 0x5e, 0xae, 0xeb, 0xed, 0x1e, 0xe6,
+ 0x33, 0xdc, 0xc5, 0x91, 0x82, 0x44, 0xa2, 0x62, 0x89, 0x3a, 0xc9, 0x2b, 0xdf, 0x61, 0x4c, 0x62,
+ 0xd1, 0x07, 0x30, 0xd1, 0x23, 0xfd, 0xdb, 0xea, 0xbe, 0x63, 0xba, 0xd8, 0x50, 0xdf, 0x38, 0xbc,
+ 0x2d, 0x50, 0xb0, 0x34, 0x29, 0xf2, 0xc8, 0x17, 0x2d, 0x44, 0x0c, 0xf1, 0x7e, 0x5f, 0xdf, 0x6f,
+ 0x06, 0x96, 0xb7, 0xba, 0xcf, 0x6f, 0x8f, 0xe5, 0x55, 0xde, 0x5f, 0x97, 0x89, 0x98, 0xf7, 0x13,
+ 0x9c, 0xb2, 0xf7, 0x13, 0x48, 0x74, 0x9b, 0x7e, 0x05, 0x98, 0x4b, 0xd8, 0xcd, 0xc3, 0xf9, 0x11,
+ 0x6b, 0x31, 0x6f, 0xb0, 0x61, 0x0d, 0x7f, 0x92, 0x84, 0x46, 0x12, 0xb8, 0x0f, 0xe8, 0x6b, 0x37,
+ 0xb1, 0x1f, 0xb8, 0x16, 0x36, 0x78, 0x1b, 0x35, 0xea, 0x03, 0x89, 0x2a, 0xf2, 0x81, 0x04, 0x1d,
+ 0xf1, 0x81, 0x84, 0x45, 0x9f, 0xc0, 0x6c, 0xe2, 0x1e, 0x15, 0x7b, 0x8f, 0x92, 0xea, 0x00, 0x63,
+ 0x4d, 0x41, 0xc9, 0x3a, 0x5e, 0x95, 0x0c, 0x49, 0xb3, 0x52, 0x0b, 0xd1, 0xde, 0xd5, 0xad, 0xee,
+ 0x9a, 0xdd, 0x96, 0x63, 0x6e, 0x42, 0xa5, 0xfd, 0xba, 0x82, 0x92, 0x69, 0x57, 0xc9, 0x90, 0xb5,
+ 0xab, 0x28, 0xa2, 0x3b, 0x53, 0xa4, 0x88, 0x89, 0xee, 0x16, 0xaa, 0xee, 0x4c, 0x31, 0x02, 0xe1,
+ 0xce, 0x14, 0x03, 0x28, 0xee, 0x4c, 0x71, 0xca, 0x42, 0x38, 0xe7, 0xa9, 0xbd, 0x07, 0xd3, 0x89,
+ 0xf4, 0x82, 0xde, 0x86, 0xe8, 0x26, 0xce, 0xbd, 0x03, 0x27, 0xac, 0x5d, 0xa5, 0x9b, 0x3b, 0x04,
+ 0xae, 0xba, 0xb9, 0x43, 0xe0, 0xb5, 0x2f, 0x32, 0x50, 0x08, 0x23, 0xea, 0x44, 0xba, 0x91, 0x65,
+ 0xc8, 0xf7, 0xb1, 0x47, 0x6f, 0xdb, 0xa4, 0xe2, 0xa2, 0x86, 0x83, 0xc4, 0xa2, 0x86, 0x83, 0xe4,
+ 0x9a, 0x2b, 0xfd, 0x48, 0x35, 0x57, 0xe6, 0xc8, 0x35, 0x17, 0xa6, 0x07, 0xcc, 0x42, 0x5e, 0x0c,
+ 0x0f, 0x46, 0x1e, 0x9e, 0x6c, 0xc3, 0xe3, 0x67, 0x91, 0x31, 0x71, 0xfc, 0x2c, 0xa2, 0xd0, 0x2e,
+ 0x9c, 0x16, 0x0e, 0x6f, 0xf8, 0xd4, 0x8e, 0x64, 0xa8, 0xa9, 0xf1, 0xa7, 0xf9, 0x4d, 0x4a, 0xc5,
+ 0xf6, 0xe1, 0x6e, 0x02, 0x2a, 0x16, 0xad, 0x49, 0x1c, 0x09, 0x09, 0x03, 0xb7, 0x83, 0xee, 0x3a,
+ 0x37, 0x7b, 0x3e, 0x0e, 0x09, 0x11, 0x2e, 0x86, 0x84, 0x08, 0xaf, 0xfd, 0x2d, 0x05, 0x53, 0xf2,
+ 0xfb, 0x9e, 0x48, 0x60, 0xbc, 0x0a, 0x45, 0xbc, 0x6f, 0xfa, 0xad, 0x8e, 0x6d, 0x60, 0xde, 0xb9,
+ 0x51, 0x3f, 0x13, 0xe0, 0x55, 0xdb, 0x90, 0xfc, 0x1c, 0xc2, 0xc4, 0x68, 0x4a, 0x1f, 0x29, 0x9a,
+ 0xe2, 0x21, 0x69, 0xe6, 0x08, 0x43, 0x52, 0xa5, 0x9f, 0x8a, 0x27, 0xe3, 0xa7, 0xda, 0xd7, 0x29,
+ 0x28, 0x27, 0xd3, 0xee, 0xd3, 0xb1, 0x05, 0xe5, 0xdd, 0x94, 0x3e, 0xf2, 0x6e, 0x7a, 0x07, 0x26,
+ 0x49, 0x65, 0xa6, 0xfb, 0x3e, 0xbf, 0x9c, 0x9b, 0xa1, 0xc5, 0x15, 0xcb, 0x46, 0x81, 0xb5, 0x12,
+ 0xc2, 0xa5, 0x6c, 0x24, 0xc0, 0x47, 0x42, 0x37, 0x7b, 0xcc, 0xd0, 0xfd, 0x2c, 0x05, 0x93, 0x1b,
+ 0xb6, 0x71, 0x8f, 0x15, 0x6d, 0xfe, 0xd3, 0x62, 0xcf, 0x27, 0x99, 0xd2, 0x6a, 0xd3, 0x30, 0x29,
+ 0x55, 0x6d, 0xb5, 0xcf, 0x59, 0x9c, 0xc9, 0x9f, 0xab, 0x7f, 0x3d, 0xbb, 0x4c, 0xc1, 0x84, 0x58,
+ 0xfe, 0xd5, 0x1a, 0x30, 0x9d, 0xa8, 0xd6, 0xc4, 0x17, 0xd0, 0x8e, 0xf2, 0x02, 0xb5, 0x6b, 0x30,
+ 0xab, 0x2a, 0x63, 0x84, 0xac, 0xa3, 0x1d, 0xe1, 0x64, 0xe7, 0x3a, 0xcc, 0xaa, 0xca, 0x91, 0xe3,
+ 0x2f, 0xe7, 0x6d, 0x7e, 0x6a, 0xca, 0x0a, 0x87, 0xe3, 0xf3, 0xff, 0x29, 0xea, 0x9e, 0xe3, 0x8b,
+ 0xf0, 0xef, 0x42, 0xd9, 0x09, 0x1f, 0x5a, 0xbc, 0x47, 0x63, 0xdb, 0x92, 0x76, 0x1c, 0x11, 0x6e,
+ 0x2d, 0xd1, 0xac, 0x4d, 0xc9, 0x18, 0x59, 0x0e, 0xef, 0xdf, 0x72, 0x0a, 0x39, 0xcd, 0x44, 0x23,
+ 0x37, 0x25, 0x63, 0x04, 0xd3, 0xe6, 0x0f, 0x37, 0x2d, 0xed, 0xff, 0xb2, 0xa4, 0x69, 0x9e, 0x4e,
+ 0x5c, 0xd4, 0x47, 0x97, 0xa1, 0x40, 0x7f, 0x45, 0x17, 0x77, 0xbe, 0xd4, 0x3a, 0x14, 0x26, 0x2d,
+ 0x20, 0xcf, 0x41, 0xe8, 0x35, 0x28, 0x46, 0x77, 0xf7, 0xf9, 0x79, 0x29, 0x8b, 0xbb, 0x10, 0x28,
+ 0xc5, 0x5d, 0x08, 0xe4, 0x4d, 0xf3, 0xff, 0xc1, 0xd9, 0xb1, 0xb7, 0xf6, 0x8f, 0x75, 0x36, 0x17,
+ 0x77, 0xbf, 0x99, 0x63, 0x75, 0xbf, 0xfb, 0x30, 0xaf, 0xbe, 0x4c, 0x2f, 0x68, 0x4f, 0x1d, 0xaa,
+ 0x3d, 0xb6, 0x7e, 0xfa, 0x88, 0xd6, 0x4f, 0xd5, 0x76, 0xe9, 0xb8, 0x20, 0xba, 0xb4, 0x8e, 0x2e,
+ 0x41, 0xd6, 0xb1, 0xed, 0x9e, 0xc7, 0x2f, 0x24, 0x50, 0x75, 0x14, 0x20, 0xaa, 0xa3, 0x80, 0x47,
+ 0x18, 0x4e, 0x04, 0x61, 0x04, 0xc7, 0x57, 0xf0, 0x9f, 0x80, 0x75, 0x5f, 0xbc, 0x0c, 0x85, 0xf0,
+ 0xd0, 0x17, 0x01, 0xe4, 0xde, 0xdb, 0x5a, 0xdd, 0x5a, 0xbd, 0x56, 0x3e, 0x85, 0x4a, 0x90, 0xdf,
+ 0x58, 0xbd, 0x73, 0xed, 0xe6, 0x9d, 0xeb, 0x65, 0x8d, 0x3c, 0x34, 0xb7, 0xee, 0xdc, 0x21, 0x0f,
+ 0xa9, 0x17, 0x6f, 0x8b, 0x17, 0xc9, 0x78, 0xe5, 0x36, 0x01, 0x85, 0x15, 0xc7, 0xa1, 0x29, 0x84,
+ 0xf1, 0xae, 0xee, 0x99, 0x64, 0x27, 0x97, 0x35, 0x94, 0x87, 0xf4, 0xdd, 0xbb, 0xeb, 0xe5, 0x14,
+ 0x9a, 0x85, 0xf2, 0x35, 0xac, 0x1b, 0x3d, 0xd3, 0xc2, 0x61, 0xde, 0x2a, 0xa7, 0x1b, 0x0f, 0x7e,
+ 0xff, 0xed, 0xa2, 0xf6, 0xf5, 0xb7, 0x8b, 0xda, 0x5f, 0xbf, 0x5d, 0xd4, 0xbe, 0xf8, 0x6e, 0xf1,
+ 0xd4, 0xd7, 0xdf, 0x2d, 0x9e, 0xfa, 0xf3, 0x77, 0x8b, 0xa7, 0xfe, 0xe7, 0x72, 0xd7, 0xf4, 0x77,
+ 0x82, 0x76, 0xbd, 0x63, 0xf7, 0xf9, 0xcf, 0x81, 0x1d, 0xd7, 0x26, 0x09, 0x82, 0x3f, 0x2d, 0x27,
+ 0x7f, 0x27, 0xfc, 0xcb, 0xd4, 0xb9, 0x15, 0xfa, 0xb8, 0xc1, 0xe8, 0xea, 0x37, 0xed, 0x3a, 0x03,
+ 0xd0, 0x5f, 0x86, 0x7a, 0xed, 0x1c, 0xfd, 0x05, 0xe8, 0xab, 0xff, 0x08, 0x00, 0x00, 0xff, 0xff,
+ 0xbd, 0x84, 0x96, 0x8f, 0x62, 0x3c, 0x00, 0x00,
}
func (m *EventSequence) Marshal() (dAtA []byte, err error) {
@@ -4566,6 +4586,32 @@ func (m *ResourceUtilisation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.AvgResourcesForPeriod) > 0 {
+ for k := range m.AvgResourcesForPeriod {
+ v := m.AvgResourcesForPeriod[k]
+ baseI := i
+ if v != nil {
+ {
+ size, err := v.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintEvents(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ i -= len(k)
+ copy(dAtA[i:], k)
+ i = encodeVarintEvents(dAtA, i, uint64(len(k)))
+ i--
+ dAtA[i] = 0xa
+ i = encodeVarintEvents(dAtA, i, uint64(baseI-i))
+ i--
+ dAtA[i] = 0x42
+ }
+ }
if len(m.RunId) > 0 {
i -= len(m.RunId)
copy(dAtA[i:], m.RunId)
@@ -5349,20 +5395,20 @@ func (m *JobSetFilter) MarshalToSizedBuffer(dAtA []byte) (int, error) {
var l int
_ = l
if len(m.States) > 0 {
- dAtA41 := make([]byte, len(m.States)*10)
- var j40 int
+ dAtA42 := make([]byte, len(m.States)*10)
+ var j41 int
for _, num := range m.States {
for num >= 1<<7 {
- dAtA41[j40] = uint8(uint64(num)&0x7f | 0x80)
+ dAtA42[j41] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
- j40++
+ j41++
}
- dAtA41[j40] = uint8(num)
- j40++
+ dAtA42[j41] = uint8(num)
+ j41++
}
- i -= j40
- copy(dAtA[i:], dAtA41[:j40])
- i = encodeVarintEvents(dAtA, i, uint64(j40))
+ i -= j41
+ copy(dAtA[i:], dAtA42[:j41])
+ i = encodeVarintEvents(dAtA, i, uint64(j41))
i--
dAtA[i] = 0xa
}
@@ -5397,20 +5443,20 @@ func (m *CancelJobSet) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x12
}
if len(m.States) > 0 {
- dAtA43 := make([]byte, len(m.States)*10)
- var j42 int
+ dAtA44 := make([]byte, len(m.States)*10)
+ var j43 int
for _, num := range m.States {
for num >= 1<<7 {
- dAtA43[j42] = uint8(uint64(num)&0x7f | 0x80)
+ dAtA44[j43] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
- j42++
+ j43++
}
- dAtA43[j42] = uint8(num)
- j42++
+ dAtA44[j43] = uint8(num)
+ j43++
}
- i -= j42
- copy(dAtA[i:], dAtA43[:j42])
- i = encodeVarintEvents(dAtA, i, uint64(j42))
+ i -= j43
+ copy(dAtA[i:], dAtA44[:j43])
+ i = encodeVarintEvents(dAtA, i, uint64(j43))
i--
dAtA[i] = 0xa
}
@@ -5437,6 +5483,13 @@ func (m *CancelledJob) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
+ if len(m.CancelUser) > 0 {
+ i -= len(m.CancelUser)
+ copy(dAtA[i:], m.CancelUser)
+ i = encodeVarintEvents(dAtA, i, uint64(len(m.CancelUser)))
+ i--
+ dAtA[i] = 0x22
+ }
if len(m.JobId) > 0 {
i -= len(m.JobId)
copy(dAtA[i:], m.JobId)
@@ -7485,6 +7538,19 @@ func (m *ResourceUtilisation) Size() (n int) {
if l > 0 {
n += 1 + l + sovEvents(uint64(l))
}
+ if len(m.AvgResourcesForPeriod) > 0 {
+ for k, v := range m.AvgResourcesForPeriod {
+ _ = k
+ _ = v
+ l = 0
+ if v != nil {
+ l = v.Size()
+ l += 1 + sovEvents(uint64(l))
+ }
+ mapEntrySize := 1 + len(k) + sovEvents(uint64(len(k))) + l
+ n += mapEntrySize + 1 + sovEvents(uint64(mapEntrySize))
+ }
+ }
return n
}
@@ -7840,6 +7906,10 @@ func (m *CancelledJob) Size() (n int) {
if l > 0 {
n += 1 + l + sovEvents(uint64(l))
}
+ l = len(m.CancelUser)
+ if l > 0 {
+ n += 1 + l + sovEvents(uint64(l))
+ }
return n
}
@@ -10108,6 +10178,135 @@ func (m *ResourceUtilisation) Unmarshal(dAtA []byte) error {
}
m.RunId = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 8:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AvgResourcesForPeriod", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowEvents
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthEvents
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthEvents
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.AvgResourcesForPeriod == nil {
+ m.AvgResourcesForPeriod = make(map[string]*resource.Quantity)
+ }
+ var mapkey string
+ var mapvalue *resource.Quantity
+ for iNdEx < postIndex {
+ entryPreIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowEvents
+ }
+ 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 ErrIntOverflowEvents
+ }
+ 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 ErrInvalidLengthEvents
+ }
+ postStringIndexmapkey := iNdEx + intStringLenmapkey
+ if postStringIndexmapkey < 0 {
+ return ErrInvalidLengthEvents
+ }
+ 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 ErrIntOverflowEvents
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ mapmsglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if mapmsglen < 0 {
+ return ErrInvalidLengthEvents
+ }
+ postmsgIndex := iNdEx + mapmsglen
+ if postmsgIndex < 0 {
+ return ErrInvalidLengthEvents
+ }
+ if postmsgIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ mapvalue = &resource.Quantity{}
+ if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
+ return err
+ }
+ iNdEx = postmsgIndex
+ } else {
+ iNdEx = entryPreIndex
+ skippy, err := skipEvents(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthEvents
+ }
+ if (iNdEx + skippy) > postIndex {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+ m.AvgResourcesForPeriod[mapkey] = mapvalue
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipEvents(dAtA[iNdEx:])
@@ -12378,6 +12577,38 @@ func (m *CancelledJob) Unmarshal(dAtA []byte) error {
}
m.JobId = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field CancelUser", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowEvents
+ }
+ 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 ErrInvalidLengthEvents
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthEvents
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.CancelUser = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipEvents(dAtA[iNdEx:])
diff --git a/pkg/armadaevents/events.proto b/pkg/armadaevents/events.proto
index 8905344026b..0db2d9bbf73 100644
--- a/pkg/armadaevents/events.proto
+++ b/pkg/armadaevents/events.proto
@@ -115,6 +115,7 @@ message ResourceUtilisation {
map total_cumulative_usage = 5;
string job_id = 6;
string run_id = 7;
+ map avg_resources_for_period = 8;
}
@@ -273,6 +274,7 @@ message CancelledJob {
reserved 1;
string reason = 2;
string job_id = 3;
+ string cancel_user = 4;
}
message JobSucceeded {
diff --git a/scripts/common.sh b/scripts/common.sh
index c9879dd1b15..7c1c33c43c3 100755
--- a/scripts/common.sh
+++ b/scripts/common.sh
@@ -11,7 +11,9 @@ export image_names=(
"armada-executor"
"armada-fakeexecutor"
"armada-lookout-ingester-v2"
+ "armada-lookout-ingester"
"armada-lookout-v2"
+ "armada-lookout"
"armada-event-ingester"
"armada-scheduler"
"armada-scheduler-ingester"