diff --git a/Cargo.lock b/Cargo.lock
index c450ffb11a..438a7e39af 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -253,72 +253,6 @@ dependencies = [
"backtrace",
]
-[[package]]
-name = "api-actor"
-version = "25.1.0-rc.1"
-dependencies = [
- "api-helper",
- "base64 0.13.1",
- "build",
- "build-create",
- "build-get",
- "build-list-for-env",
- "cdn-namespace-domain-create",
- "chirp-client",
- "chrono",
- "cloud-namespace-token-development-create",
- "cloud-namespace-token-public-create",
- "cluster",
- "ds",
- "ds-log-export",
- "ds-log-read",
- "faker-build",
- "faker-game",
- "faker-game-namespace",
- "faker-game-version",
- "faker-region",
- "game-get",
- "game-namespace-get",
- "game-namespace-resolve-name-id",
- "game-resolve-name-id",
- "game-version-get",
- "http 0.2.12",
- "hyper 0.14.31",
- "lazy_static",
- "pegboard",
- "region-get",
- "region-recommend",
- "reqwest 0.11.27",
- "rivet-api",
- "rivet-cache",
- "rivet-claims",
- "rivet-config",
- "rivet-connection",
- "rivet-convert",
- "rivet-env",
- "rivet-health-checks",
- "rivet-operation",
- "rivet-pools",
- "rivet-util-team",
- "s3-util",
- "serde",
- "serde_json",
- "team-get",
- "token-create",
- "token-revoke",
- "tokio",
- "tracing",
- "tracing-futures",
- "tracing-subscriber",
- "upload-complete",
- "upload-get",
- "url",
- "user-get",
- "user-identity-get",
- "user-team-list",
- "uuid",
-]
-
[[package]]
name = "api-auth"
version = "25.1.0-rc.1"
@@ -491,30 +425,421 @@ dependencies = [
"rivet-operation",
"rivet-pools",
"rivet-util-job",
- "rivet-util-mm",
- "rivet-util-team",
+ "rivet-util-mm",
+ "rivet-util-team",
+ "s3-util",
+ "serde",
+ "serde_json",
+ "team-get",
+ "team-member-count",
+ "team-validate",
+ "thiserror 1.0.69",
+ "tier",
+ "token-create",
+ "token-revoke",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "upload-complete",
+ "upload-file-list",
+ "upload-get",
+ "upload-prepare",
+ "url",
+ "user-get",
+ "user-identity-create",
+ "user-identity-get",
+ "user-team-list",
+ "uuid",
+]
+
+[[package]]
+name = "api-core-actor"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-helper",
+ "base64 0.13.1",
+ "build",
+ "build-create",
+ "build-get",
+ "build-list-for-env",
+ "cdn-namespace-domain-create",
+ "chirp-client",
+ "chrono",
+ "cloud-namespace-token-development-create",
+ "cloud-namespace-token-public-create",
+ "cluster",
+ "ds",
+ "ds-log-export",
+ "ds-log-read",
+ "faker-build",
+ "faker-game",
+ "faker-game-namespace",
+ "faker-game-version",
+ "faker-region",
+ "game-get",
+ "game-namespace-get",
+ "game-namespace-resolve-name-id",
+ "game-resolve-name-id",
+ "game-version-get",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "lazy_static",
+ "pegboard",
+ "region-get",
+ "region-recommend",
+ "reqwest 0.11.27",
+ "rivet-api",
+ "rivet-cache",
+ "rivet-claims",
+ "rivet-config",
+ "rivet-connection",
+ "rivet-convert",
+ "rivet-env",
+ "rivet-health-checks",
+ "rivet-operation",
+ "rivet-pools",
+ "rivet-util-team",
+ "s3-util",
+ "serde",
+ "serde_json",
+ "team-get",
+ "token-create",
+ "token-revoke",
+ "tokio",
+ "tracing",
+ "tracing-futures",
+ "tracing-subscriber",
+ "upload-complete",
+ "upload-get",
+ "url",
+ "user-get",
+ "user-identity-get",
+ "user-team-list",
+ "uuid",
+]
+
+[[package]]
+name = "api-core-intercom"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-helper",
+ "async-trait",
+ "chirp-client",
+ "chirp-workflow",
+ "chrono",
+ "edge-pegboard",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "lazy_static",
+ "prost 0.10.4",
+ "rivet-api",
+ "rivet-cache",
+ "rivet-claims",
+ "rivet-config",
+ "rivet-convert",
+ "rivet-env",
+ "rivet-health-checks",
+ "rivet-operation",
+ "rivet-pools",
+ "serde",
+ "serde_json",
+ "thiserror 1.0.69",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+ "uuid",
+]
+
+[[package]]
+name = "api-core-monolith-edge"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-core-intercom",
+ "api-core-traefik-provider",
+ "api-helper",
+ "api-provision",
+ "async-trait",
+ "chirp-client",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "rivet-config",
+ "rivet-env",
+ "rivet-operation",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+]
+
+[[package]]
+name = "api-core-monolith-public"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-auth",
+ "api-cf-verification",
+ "api-cloud",
+ "api-core-actor",
+ "api-games",
+ "api-group",
+ "api-helper",
+ "api-identity",
+ "api-job",
+ "api-matchmaker",
+ "api-portal",
+ "api-status",
+ "api-ui",
+ "async-trait",
+ "chirp-client",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "rivet-config",
+ "rivet-env",
+ "rivet-operation",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+]
+
+[[package]]
+name = "api-core-traefik-provider"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-helper",
+ "async-trait",
+ "async_once",
+ "base64 0.13.1",
+ "cdn-namespace-auth-user-update",
+ "cdn-namespace-domain-create",
+ "chirp-client",
+ "chrono",
+ "cluster",
+ "ds",
+ "faker-cdn-site",
+ "faker-game",
+ "faker-game-namespace",
+ "faker-game-version",
+ "faker-job-run",
+ "faker-region",
+ "game-get",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "lazy_static",
+ "prost 0.10.4",
+ "reqwest 0.11.27",
+ "rivet-cache",
+ "rivet-claims",
+ "rivet-config",
+ "rivet-connection",
+ "rivet-convert",
+ "rivet-env",
+ "rivet-health-checks",
+ "rivet-operation",
+ "rivet-pools",
+ "rivet-route",
+ "rivet-util-cdn",
+ "rivet-util-job",
+ "s3-util",
+ "serde",
+ "serde_json",
+ "sqlx",
+ "thiserror 1.0.69",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+ "uuid",
+]
+
+[[package]]
+name = "api-edge-actor"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-helper",
+ "base64 0.13.1",
+ "build",
+ "build-create",
+ "build-get",
+ "build-list-for-env",
+ "cdn-namespace-domain-create",
+ "chirp-client",
+ "chirp-workflow",
+ "chrono",
+ "cloud-namespace-token-development-create",
+ "cloud-namespace-token-public-create",
+ "cluster",
+ "ds",
+ "ds-log-export",
+ "ds-log-read",
+ "faker-build",
+ "faker-game",
+ "faker-game-namespace",
+ "faker-game-version",
+ "faker-region",
+ "game-get",
+ "game-namespace-get",
+ "game-namespace-resolve-name-id",
+ "game-resolve-name-id",
+ "game-version-get",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "lazy_static",
+ "pegboard",
+ "region-get",
+ "region-recommend",
+ "reqwest 0.11.27",
+ "rivet-api",
+ "rivet-cache",
+ "rivet-claims",
+ "rivet-config",
+ "rivet-connection",
+ "rivet-convert",
+ "rivet-env",
+ "rivet-health-checks",
+ "rivet-operation",
+ "rivet-pools",
+ "rivet-util-team",
+ "s3-util",
+ "serde",
+ "serde_json",
+ "team-get",
+ "token-create",
+ "token-revoke",
+ "tokio",
+ "tracing",
+ "tracing-futures",
+ "tracing-subscriber",
+ "upload-complete",
+ "upload-get",
+ "url",
+ "user-get",
+ "user-identity-get",
+ "user-team-list",
+ "uuid",
+]
+
+[[package]]
+name = "api-edge-intercom"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-helper",
+ "async-trait",
+ "chirp-client",
+ "chirp-workflow",
+ "chrono",
+ "edge-pegboard",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "lazy_static",
+ "prost 0.10.4",
+ "rivet-api",
+ "rivet-cache",
+ "rivet-claims",
+ "rivet-config",
+ "rivet-convert",
+ "rivet-env",
+ "rivet-health-checks",
+ "rivet-operation",
+ "rivet-pools",
+ "serde",
+ "serde_json",
+ "thiserror 1.0.69",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+ "uuid",
+]
+
+[[package]]
+name = "api-edge-monolith-edge"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-edge-traefik-provider",
+ "api-helper",
+ "async-trait",
+ "chirp-client",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "rivet-config",
+ "rivet-env",
+ "rivet-operation",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+]
+
+[[package]]
+name = "api-edge-monolith-public"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-edge-actor",
+ "api-edge-intercom",
+ "api-helper",
+ "async-trait",
+ "chirp-client",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "rivet-config",
+ "rivet-env",
+ "rivet-operation",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+]
+
+[[package]]
+name = "api-edge-traefik-provider"
+version = "25.1.0-rc.1"
+dependencies = [
+ "api-core-traefik-provider",
+ "api-helper",
+ "async-trait",
+ "async_once",
+ "base64 0.13.1",
+ "cdn-namespace-auth-user-update",
+ "cdn-namespace-domain-create",
+ "chirp-client",
+ "chirp-workflow",
+ "chrono",
+ "cluster",
+ "ds",
+ "faker-cdn-site",
+ "faker-game",
+ "faker-game-namespace",
+ "faker-game-version",
+ "faker-job-run",
+ "faker-region",
+ "game-get",
+ "http 0.2.12",
+ "hyper 0.14.31",
+ "lazy_static",
+ "prost 0.10.4",
+ "reqwest 0.11.27",
+ "rivet-cache",
+ "rivet-claims",
+ "rivet-config",
+ "rivet-connection",
+ "rivet-convert",
+ "rivet-env",
+ "rivet-health-checks",
+ "rivet-operation",
+ "rivet-pools",
+ "rivet-route",
+ "rivet-util-cdn",
+ "rivet-util-job",
"s3-util",
"serde",
"serde_json",
- "team-get",
- "team-member-count",
- "team-validate",
+ "sqlx",
"thiserror 1.0.69",
- "tier",
- "token-create",
- "token-revoke",
"tokio",
"tracing",
"tracing-subscriber",
- "upload-complete",
- "upload-file-list",
- "upload-get",
- "upload-prepare",
"url",
- "user-get",
- "user-identity-create",
- "user-identity-get",
- "user-team-list",
"uuid",
]
@@ -857,56 +1182,6 @@ dependencies = [
"uuid",
]
-[[package]]
-name = "api-monolith-edge"
-version = "25.1.0-rc.1"
-dependencies = [
- "api-helper",
- "api-provision",
- "api-traefik-provider",
- "async-trait",
- "chirp-client",
- "http 0.2.12",
- "hyper 0.14.31",
- "rivet-config",
- "rivet-env",
- "rivet-operation",
- "tokio",
- "tracing",
- "tracing-subscriber",
- "url",
-]
-
-[[package]]
-name = "api-monolith-public"
-version = "25.1.0-rc.1"
-dependencies = [
- "api-actor",
- "api-auth",
- "api-cf-verification",
- "api-cloud",
- "api-games",
- "api-group",
- "api-helper",
- "api-identity",
- "api-job",
- "api-matchmaker",
- "api-portal",
- "api-status",
- "api-ui",
- "async-trait",
- "chirp-client",
- "http 0.2.12",
- "hyper 0.14.31",
- "rivet-config",
- "rivet-env",
- "rivet-operation",
- "tokio",
- "tracing",
- "tracing-subscriber",
- "url",
-]
-
[[package]]
name = "api-portal"
version = "25.1.0-rc.1"
@@ -1031,56 +1306,6 @@ dependencies = [
"uuid",
]
-[[package]]
-name = "api-traefik-provider"
-version = "25.1.0-rc.1"
-dependencies = [
- "api-helper",
- "async-trait",
- "async_once",
- "base64 0.13.1",
- "cdn-namespace-auth-user-update",
- "cdn-namespace-domain-create",
- "chirp-client",
- "chrono",
- "cluster",
- "ds",
- "faker-cdn-site",
- "faker-game",
- "faker-game-namespace",
- "faker-game-version",
- "faker-job-run",
- "faker-region",
- "game-get",
- "http 0.2.12",
- "hyper 0.14.31",
- "lazy_static",
- "prost 0.10.4",
- "reqwest 0.11.27",
- "rivet-cache",
- "rivet-claims",
- "rivet-config",
- "rivet-connection",
- "rivet-convert",
- "rivet-env",
- "rivet-health-checks",
- "rivet-operation",
- "rivet-pools",
- "rivet-route",
- "rivet-util-cdn",
- "rivet-util-job",
- "s3-util",
- "serde",
- "serde_json",
- "sqlx",
- "thiserror 1.0.69",
- "tokio",
- "tracing",
- "tracing-subscriber",
- "url",
- "uuid",
-]
-
[[package]]
name = "api-ui"
version = "25.1.0-rc.1"
@@ -3320,6 +3545,7 @@ dependencies = [
"pegboard",
"rand",
"reqwest 0.11.27",
+ "rivet-api",
"rivet-config",
"rivet-metrics",
"rivet-operation",
@@ -5472,12 +5698,78 @@ dependencies = [
]
[[package]]
-name = "edge-monolith-workflow-worker"
+name = "edge-ds"
version = "25.1.0-rc.1"
dependencies = [
+ "anyhow",
+ "bit-vec",
+ "build",
+ "build-get",
+ "chirp-client",
+ "chirp-worker",
"chirp-workflow",
- "ds",
+ "chrono",
+ "cjson",
+ "cluster",
+ "edge-pegboard",
+ "faker-build",
+ "faker-game",
+ "faker-region",
+ "faker-user",
+ "fdb-util",
+ "foundationdb",
+ "game-get",
+ "game-namespace-get",
+ "game-resolve-namespace-id",
+ "heck 0.3.3",
+ "hex",
+ "http 0.2.12",
+ "ip-info",
+ "lazy_static",
+ "mm-config-version-get",
+ "mm-lobby-get",
+ "mm-lobby-list-for-user-id",
+ "nix 0.27.1",
+ "nomad-client",
+ "nomad-util",
+ "nomad_client",
"pegboard",
+ "rand",
+ "regex",
+ "region-get",
+ "reqwest 0.12.9",
+ "rivet-api",
+ "rivet-config",
+ "rivet-convert",
+ "rivet-health-checks",
+ "rivet-metrics",
+ "rivet-operation",
+ "rivet-runtime",
+ "rivet-util",
+ "rivet-util-build",
+ "rivet-util-job",
+ "s3-util",
+ "serde",
+ "serde_json",
+ "sha2 0.10.8",
+ "sqlite-util",
+ "sqlx",
+ "strum 0.24.1",
+ "tier",
+ "token-create",
+ "tracing-subscriber",
+ "upload-get",
+ "user-identity-get",
+ "uuid",
+]
+
+[[package]]
+name = "edge-monolith-workflow-worker"
+version = "25.1.0-rc.1"
+dependencies = [
+ "chirp-workflow",
+ "edge-ds",
+ "edge-pegboard",
"rivet-config",
"rivet-health-checks",
"rivet-metrics",
@@ -5488,10 +5780,14 @@ dependencies = [
name = "edge-pegboard"
version = "25.1.0-rc.1"
dependencies = [
+ "anyhow",
"chirp-workflow",
+ "fdb-util",
+ "foundationdb",
"lazy_static",
"nix 0.27.1",
"pegboard",
+ "rivet-api",
"rivet-config",
"rivet-metrics",
"rivet-util",
@@ -5499,12 +5795,32 @@ dependencies = [
"serde",
"serde_json",
"server-spec",
+ "sqlite-util",
"sqlx",
"strum 0.24.1",
"thiserror 1.0.69",
"uuid",
]
+[[package]]
+name = "edge-pegboard-ws"
+version = "25.1.0-rc.1"
+dependencies = [
+ "chirp-client",
+ "chirp-workflow",
+ "edge-pegboard",
+ "hyper 1.5.1",
+ "pegboard",
+ "rivet-config",
+ "rivet-connection",
+ "rivet-health-checks",
+ "rivet-metrics",
+ "rivet-runtime",
+ "serde",
+ "tokio-tungstenite 0.23.1",
+ "url",
+]
+
[[package]]
name = "either"
version = "1.13.0"
@@ -6017,6 +6333,7 @@ version = "25.1.0-rc.1"
dependencies = [
"anyhow",
"foundationdb",
+ "global-error",
"lazy_static",
"tokio",
"tracing",
@@ -9271,10 +9588,8 @@ version = "25.1.0-rc.1"
dependencies = [
"chirp-workflow",
"cluster",
- "ds",
"job-run",
"linode",
- "pegboard",
"rivet-config",
"rivet-health-checks",
"rivet-metrics",
@@ -11792,6 +12107,27 @@ dependencies = [
"user-team-list",
]
+[[package]]
+name = "rivet-edge-server"
+version = "25.1.0-rc.1"
+dependencies = [
+ "anyhow",
+ "api-edge-monolith-edge",
+ "api-edge-monolith-public",
+ "chirp-workflow",
+ "clap",
+ "edge-monolith-workflow-worker",
+ "edge-pegboard-ws",
+ "rivet-cache",
+ "rivet-config",
+ "rivet-connection",
+ "rivet-migrate",
+ "rivet-runtime",
+ "rivet-server-cli",
+ "rivet-service-manager",
+ "s3-util",
+]
+
[[package]]
name = "rivet-env"
version = "25.1.0-rc.1"
@@ -12077,6 +12413,7 @@ dependencies = [
"redis",
"rivet-config",
"rivet-metrics",
+ "sqlite-util",
"sqlx",
"tempfile",
"thiserror 1.0.69",
@@ -12153,8 +12490,8 @@ name = "rivet-server"
version = "25.1.0-rc.1"
dependencies = [
"anyhow",
- "api-monolith-edge",
- "api-monolith-public",
+ "api-core-monolith-edge",
+ "api-core-monolith-public",
"build-default-create",
"chirp-client",
"chirp-workflow",
@@ -12176,10 +12513,6 @@ dependencies = [
"monolith-worker",
"monolith-workflow-worker",
"nomad-monitor",
- "pegboard-dc-init",
- "pegboard-gc",
- "pegboard-metrics-publish",
- "pegboard-ws",
"rivet-cache",
"rivet-config",
"rivet-connection",
@@ -12190,8 +12523,6 @@ dependencies = [
"s3-util",
"telemetry-beacon",
"user-delete-pending",
- "workflow-gc",
- "workflow-metrics-publish",
]
[[package]]
@@ -17057,41 +17388,6 @@ version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
-[[package]]
-name = "workflow-gc"
-version = "25.1.0-rc.1"
-dependencies = [
- "chirp-client",
- "chirp-worker",
- "rivet-config",
- "rivet-connection",
- "rivet-health-checks",
- "rivet-metrics",
- "rivet-operation",
- "rivet-runtime",
- "tokio",
- "tracing",
- "tracing-logfmt",
- "tracing-subscriber",
-]
-
-[[package]]
-name = "workflow-metrics-publish"
-version = "25.1.0-rc.1"
-dependencies = [
- "chirp-client",
- "chirp-workflow",
- "rivet-config",
- "rivet-connection",
- "rivet-health-checks",
- "rivet-metrics",
- "rivet-runtime",
- "sqlx",
- "tokio",
- "tracing",
- "tracing-subscriber",
-]
-
[[package]]
name = "write16"
version = "1.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index 0aeb0ad3bf..4a9690654b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
[workspace]
resolver = "2"
-members = ["packages/api/actor","packages/api/auth","packages/api/cf-verification","packages/api/cloud","packages/api/games","packages/api/group","packages/api/identity","packages/api/job","packages/api/matchmaker","packages/api/monolith-edge","packages/api/monolith-public","packages/api/portal","packages/api/provision","packages/api/status","packages/api/traefik-provider","packages/api/ui","packages/common/api-helper/build","packages/common/api-helper/macros","packages/common/cache/build","packages/common/cache/result","packages/common/chirp-workflow/core","packages/common/chirp-workflow/macros","packages/common/chirp/client","packages/common/chirp/metrics","packages/common/chirp/perf","packages/common/chirp/types","packages/common/chirp/worker","packages/common/chirp/worker-attributes","packages/common/claims","packages/common/config","packages/common/connection","packages/common/convert","packages/common/deno-embed","packages/common/env","packages/common/fdb-util","packages/common/formatted-error","packages/common/global-error","packages/common/health-checks","packages/common/hub-embed","packages/common/kv-str","packages/common/metrics","packages/common/migrate","packages/common/nomad-util","packages/common/operation/core","packages/common/operation/macros","packages/common/pools","packages/common/redis-util","packages/common/runtime","packages/common/s3-util","packages/common/schemac","packages/common/server-cli","packages/common/service-manager","packages/common/smithy-output/api-auth/rust","packages/common/smithy-output/api-auth/rust-server","packages/common/smithy-output/api-cf-verification/rust","packages/common/smithy-output/api-cf-verification/rust-server","packages/common/smithy-output/api-cloud/rust","packages/common/smithy-output/api-cloud/rust-server","packages/common/smithy-output/api-group/rust","packages/common/smithy-output/api-group/rust-server","packages/common/smithy-output/api-identity/rust","packages/common/smithy-output/api-identity/rust-server","packages/common/smithy-output/api-job/rust","packages/common/smithy-output/api-job/rust-server","packages/common/smithy-output/api-kv/rust","packages/common/smithy-output/api-kv/rust-server","packages/common/smithy-output/api-matchmaker/rust","packages/common/smithy-output/api-matchmaker/rust-server","packages/common/smithy-output/api-party/rust","packages/common/smithy-output/api-party/rust-server","packages/common/smithy-output/api-portal/rust","packages/common/smithy-output/api-portal/rust-server","packages/common/smithy-output/api-status/rust","packages/common/smithy-output/api-status/rust-server","packages/common/smithy-output/api-traefik-provider/rust","packages/common/smithy-output/api-traefik-provider/rust-server","packages/common/sqlite-util","packages/common/test","packages/common/test-images","packages/common/types-proto/build","packages/common/types-proto/core","packages/common/util/core","packages/common/util/macros","packages/common/util/search","packages/infra/client/actor-kv","packages/infra/client/config","packages/infra/client/container-runner","packages/infra/client/echo","packages/infra/client/isolate-v8-runner","packages/infra/client/logs","packages/infra/client/manager","packages/infra/edge-server","packages/infra/legacy/job-runner","packages/infra/schema-generator","packages/infra/server","packages/services/build","packages/services/build/ops/create","packages/services/build/ops/get","packages/services/build/ops/list-for-env","packages/services/build/ops/list-for-game","packages/services/build/standalone/default-create","packages/services/build/util","packages/services/captcha/ops/hcaptcha-config-get","packages/services/captcha/ops/hcaptcha-verify","packages/services/captcha/ops/request","packages/services/captcha/ops/turnstile-config-get","packages/services/captcha/ops/turnstile-verify","packages/services/captcha/ops/verify","packages/services/captcha/util","packages/services/cdn/ops/namespace-auth-user-remove","packages/services/cdn/ops/namespace-auth-user-update","packages/services/cdn/ops/namespace-create","packages/services/cdn/ops/namespace-domain-create","packages/services/cdn/ops/namespace-domain-remove","packages/services/cdn/ops/namespace-get","packages/services/cdn/ops/namespace-resolve-domain","packages/services/cdn/ops/ns-auth-type-set","packages/services/cdn/ops/ns-enable-domain-public-auth-set","packages/services/cdn/ops/site-create","packages/services/cdn/ops/site-get","packages/services/cdn/ops/site-list-for-game","packages/services/cdn/ops/version-get","packages/services/cdn/ops/version-prepare","packages/services/cdn/ops/version-publish","packages/services/cdn/util","packages/services/cdn/worker","packages/services/cf-custom-hostname/ops/get","packages/services/cf-custom-hostname/ops/list-for-namespace-id","packages/services/cf-custom-hostname/ops/resolve-hostname","packages/services/cf-custom-hostname/worker","packages/services/cloud/ops/device-link-create","packages/services/cloud/ops/game-config-create","packages/services/cloud/ops/game-config-get","packages/services/cloud/ops/game-token-create","packages/services/cloud/ops/namespace-create","packages/services/cloud/ops/namespace-get","packages/services/cloud/ops/namespace-token-development-create","packages/services/cloud/ops/namespace-token-public-create","packages/services/cloud/ops/version-get","packages/services/cloud/ops/version-publish","packages/services/cloud/standalone/default-create","packages/services/cloud/worker","packages/services/cluster","packages/services/cluster/standalone/datacenter-tls-renew","packages/services/cluster/standalone/default-update","packages/services/cluster/standalone/gc","packages/services/cluster/standalone/metrics-publish","packages/services/custom-user-avatar/ops/list-for-game","packages/services/custom-user-avatar/ops/upload-complete","packages/services/debug/ops/email-res","packages/services/ds","packages/services/ds-log/ops/export","packages/services/ds-log/ops/read","packages/services/dynamic-config","packages/services/edge/monolith/standalone/workflow-worker","packages/services/edge/pegboard","packages/services/email-verification/ops/complete","packages/services/email-verification/ops/create","packages/services/email/ops/send","packages/services/external/ops/request-validate","packages/services/external/worker","packages/services/faker/ops/build","packages/services/faker/ops/cdn-site","packages/services/faker/ops/game","packages/services/faker/ops/game-namespace","packages/services/faker/ops/game-version","packages/services/faker/ops/job-run","packages/services/faker/ops/job-template","packages/services/faker/ops/mm-lobby","packages/services/faker/ops/mm-lobby-row","packages/services/faker/ops/mm-player","packages/services/faker/ops/region","packages/services/faker/ops/team","packages/services/faker/ops/user","packages/services/game/ops/banner-upload-complete","packages/services/game/ops/create","packages/services/game/ops/get","packages/services/game/ops/list-all","packages/services/game/ops/list-for-team","packages/services/game/ops/logo-upload-complete","packages/services/game/ops/namespace-create","packages/services/game/ops/namespace-get","packages/services/game/ops/namespace-list","packages/services/game/ops/namespace-resolve-name-id","packages/services/game/ops/namespace-resolve-url","packages/services/game/ops/namespace-validate","packages/services/game/ops/namespace-version-history-list","packages/services/game/ops/namespace-version-set","packages/services/game/ops/recommend","packages/services/game/ops/resolve-name-id","packages/services/game/ops/resolve-namespace-id","packages/services/game/ops/token-development-validate","packages/services/game/ops/validate","packages/services/game/ops/version-create","packages/services/game/ops/version-get","packages/services/game/ops/version-list","packages/services/game/ops/version-validate","packages/services/ip/ops/info","packages/services/job-log/ops/read","packages/services/job-log/worker","packages/services/job-run","packages/services/job/standalone/gc","packages/services/job/util","packages/services/linode","packages/services/linode/standalone/gc","packages/services/load-test/standalone/api-cloud","packages/services/load-test/standalone/mm","packages/services/load-test/standalone/mm-sustain","packages/services/load-test/standalone/sqlx","packages/services/load-test/standalone/watch-requests","packages/services/mm-config/ops/game-get","packages/services/mm-config/ops/game-upsert","packages/services/mm-config/ops/lobby-group-get","packages/services/mm-config/ops/lobby-group-resolve-name-id","packages/services/mm-config/ops/lobby-group-resolve-version","packages/services/mm-config/ops/namespace-config-set","packages/services/mm-config/ops/namespace-config-validate","packages/services/mm-config/ops/namespace-create","packages/services/mm-config/ops/namespace-get","packages/services/mm-config/ops/version-get","packages/services/mm-config/ops/version-prepare","packages/services/mm-config/ops/version-publish","packages/services/mm/ops/dev-player-token-create","packages/services/mm/ops/lobby-find-fail","packages/services/mm/ops/lobby-find-lobby-query-list","packages/services/mm/ops/lobby-find-try-complete","packages/services/mm/ops/lobby-for-run-id","packages/services/mm/ops/lobby-get","packages/services/mm/ops/lobby-history","packages/services/mm/ops/lobby-idle-update","packages/services/mm/ops/lobby-list-for-namespace","packages/services/mm/ops/lobby-list-for-user-id","packages/services/mm/ops/lobby-player-count","packages/services/mm/ops/lobby-runtime-aggregate","packages/services/mm/ops/lobby-state-get","packages/services/mm/ops/player-count-for-namespace","packages/services/mm/ops/player-get","packages/services/mm/standalone/gc","packages/services/mm/util","packages/services/mm/worker","packages/services/monolith/standalone/worker","packages/services/monolith/standalone/workflow-worker","packages/services/nomad/standalone/monitor","packages/services/pegboard","packages/services/pegboard/standalone/dc-init","packages/services/pegboard/standalone/gc","packages/services/pegboard/standalone/metrics-publish","packages/services/pegboard/standalone/ws","packages/services/region/ops/get","packages/services/region/ops/list","packages/services/region/ops/list-for-game","packages/services/region/ops/recommend","packages/services/region/ops/resolve","packages/services/region/ops/resolve-for-game","packages/services/server-spec","packages/services/team-invite/ops/get","packages/services/team-invite/worker","packages/services/team/ops/avatar-upload-complete","packages/services/team/ops/get","packages/services/team/ops/join-request-list","packages/services/team/ops/member-count","packages/services/team/ops/member-get","packages/services/team/ops/member-list","packages/services/team/ops/member-relationship-get","packages/services/team/ops/profile-validate","packages/services/team/ops/recommend","packages/services/team/ops/resolve-display-name","packages/services/team/ops/user-ban-get","packages/services/team/ops/user-ban-list","packages/services/team/ops/validate","packages/services/team/util","packages/services/team/worker","packages/services/telemetry/standalone/beacon","packages/services/tier","packages/services/token/ops/create","packages/services/token/ops/exchange","packages/services/token/ops/get","packages/services/token/ops/revoke","packages/services/upload/ops/complete","packages/services/upload/ops/file-list","packages/services/upload/ops/get","packages/services/upload/ops/list-for-user","packages/services/upload/ops/prepare","packages/services/upload/worker","packages/services/user","packages/services/user-identity/ops/create","packages/services/user-identity/ops/delete","packages/services/user-identity/ops/get","packages/services/user/ops/avatar-upload-complete","packages/services/user/ops/get","packages/services/user/ops/pending-delete-toggle","packages/services/user/ops/profile-validate","packages/services/user/ops/resolve-email","packages/services/user/ops/team-list","packages/services/user/ops/token-create","packages/services/user/standalone/delete-pending","packages/services/user/worker","packages/toolchain/actors-sdk-embed","packages/toolchain/cli","packages/toolchain/js-utils-embed","packages/toolchain/toolchain","sdks/api/full/rust"]
+members = ["packages/common/api-helper/build","packages/common/api-helper/macros","packages/common/cache/build","packages/common/cache/result","packages/common/chirp-workflow/core","packages/common/chirp-workflow/macros","packages/common/chirp/client","packages/common/chirp/metrics","packages/common/chirp/perf","packages/common/chirp/types","packages/common/chirp/worker","packages/common/chirp/worker-attributes","packages/common/claims","packages/common/config","packages/common/connection","packages/common/convert","packages/common/deno-embed","packages/common/env","packages/common/fdb-util","packages/common/formatted-error","packages/common/global-error","packages/common/health-checks","packages/common/hub-embed","packages/common/kv-str","packages/common/metrics","packages/common/migrate","packages/common/nomad-util","packages/common/operation/core","packages/common/operation/macros","packages/common/pools","packages/common/redis-util","packages/common/runtime","packages/common/s3-util","packages/common/schemac","packages/common/server-cli","packages/common/service-manager","packages/common/smithy-output/api-auth/rust","packages/common/smithy-output/api-auth/rust-server","packages/common/smithy-output/api-cf-verification/rust","packages/common/smithy-output/api-cf-verification/rust-server","packages/common/smithy-output/api-cloud/rust","packages/common/smithy-output/api-cloud/rust-server","packages/common/smithy-output/api-group/rust","packages/common/smithy-output/api-group/rust-server","packages/common/smithy-output/api-identity/rust","packages/common/smithy-output/api-identity/rust-server","packages/common/smithy-output/api-job/rust","packages/common/smithy-output/api-job/rust-server","packages/common/smithy-output/api-kv/rust","packages/common/smithy-output/api-kv/rust-server","packages/common/smithy-output/api-matchmaker/rust","packages/common/smithy-output/api-matchmaker/rust-server","packages/common/smithy-output/api-party/rust","packages/common/smithy-output/api-party/rust-server","packages/common/smithy-output/api-portal/rust","packages/common/smithy-output/api-portal/rust-server","packages/common/smithy-output/api-status/rust","packages/common/smithy-output/api-status/rust-server","packages/common/smithy-output/api-traefik-provider/rust","packages/common/smithy-output/api-traefik-provider/rust-server","packages/common/sqlite-util","packages/common/test","packages/common/test-images","packages/common/types-proto/build","packages/common/types-proto/core","packages/common/util/core","packages/common/util/macros","packages/common/util/search","packages/core/api/actor","packages/core/api/auth","packages/core/api/cf-verification","packages/core/api/cloud","packages/core/api/games","packages/core/api/group","packages/core/api/identity","packages/core/api/intercom","packages/core/api/job","packages/core/api/matchmaker","packages/core/api/monolith-edge","packages/core/api/monolith-public","packages/core/api/portal","packages/core/api/provision","packages/core/api/status","packages/core/api/traefik-provider","packages/core/api/ui","packages/core/infra/client/actor-kv","packages/core/infra/client/config","packages/core/infra/client/container-runner","packages/core/infra/client/echo","packages/core/infra/client/isolate-v8-runner","packages/core/infra/client/logs","packages/core/infra/client/manager","packages/core/infra/legacy/job-runner","packages/core/infra/schema-generator","packages/core/infra/server","packages/core/services/build","packages/core/services/build/ops/create","packages/core/services/build/ops/get","packages/core/services/build/ops/list-for-env","packages/core/services/build/ops/list-for-game","packages/core/services/build/standalone/default-create","packages/core/services/build/util","packages/core/services/captcha/ops/hcaptcha-config-get","packages/core/services/captcha/ops/hcaptcha-verify","packages/core/services/captcha/ops/request","packages/core/services/captcha/ops/turnstile-config-get","packages/core/services/captcha/ops/turnstile-verify","packages/core/services/captcha/ops/verify","packages/core/services/captcha/util","packages/core/services/cdn/ops/namespace-auth-user-remove","packages/core/services/cdn/ops/namespace-auth-user-update","packages/core/services/cdn/ops/namespace-create","packages/core/services/cdn/ops/namespace-domain-create","packages/core/services/cdn/ops/namespace-domain-remove","packages/core/services/cdn/ops/namespace-get","packages/core/services/cdn/ops/namespace-resolve-domain","packages/core/services/cdn/ops/ns-auth-type-set","packages/core/services/cdn/ops/ns-enable-domain-public-auth-set","packages/core/services/cdn/ops/site-create","packages/core/services/cdn/ops/site-get","packages/core/services/cdn/ops/site-list-for-game","packages/core/services/cdn/ops/version-get","packages/core/services/cdn/ops/version-prepare","packages/core/services/cdn/ops/version-publish","packages/core/services/cdn/util","packages/core/services/cdn/worker","packages/core/services/cf-custom-hostname/ops/get","packages/core/services/cf-custom-hostname/ops/list-for-namespace-id","packages/core/services/cf-custom-hostname/ops/resolve-hostname","packages/core/services/cf-custom-hostname/worker","packages/core/services/cloud/ops/device-link-create","packages/core/services/cloud/ops/game-config-create","packages/core/services/cloud/ops/game-config-get","packages/core/services/cloud/ops/game-token-create","packages/core/services/cloud/ops/namespace-create","packages/core/services/cloud/ops/namespace-get","packages/core/services/cloud/ops/namespace-token-development-create","packages/core/services/cloud/ops/namespace-token-public-create","packages/core/services/cloud/ops/version-get","packages/core/services/cloud/ops/version-publish","packages/core/services/cloud/standalone/default-create","packages/core/services/cloud/worker","packages/core/services/cluster","packages/core/services/cluster/standalone/datacenter-tls-renew","packages/core/services/cluster/standalone/default-update","packages/core/services/cluster/standalone/gc","packages/core/services/cluster/standalone/metrics-publish","packages/core/services/custom-user-avatar/ops/list-for-game","packages/core/services/custom-user-avatar/ops/upload-complete","packages/core/services/debug/ops/email-res","packages/core/services/ds","packages/core/services/ds-log/ops/export","packages/core/services/ds-log/ops/read","packages/core/services/dynamic-config","packages/core/services/email-verification/ops/complete","packages/core/services/email-verification/ops/create","packages/core/services/email/ops/send","packages/core/services/external/ops/request-validate","packages/core/services/external/worker","packages/core/services/faker/ops/build","packages/core/services/faker/ops/cdn-site","packages/core/services/faker/ops/game","packages/core/services/faker/ops/game-namespace","packages/core/services/faker/ops/game-version","packages/core/services/faker/ops/job-run","packages/core/services/faker/ops/job-template","packages/core/services/faker/ops/mm-lobby","packages/core/services/faker/ops/mm-lobby-row","packages/core/services/faker/ops/mm-player","packages/core/services/faker/ops/region","packages/core/services/faker/ops/team","packages/core/services/faker/ops/user","packages/core/services/game/ops/banner-upload-complete","packages/core/services/game/ops/create","packages/core/services/game/ops/get","packages/core/services/game/ops/list-all","packages/core/services/game/ops/list-for-team","packages/core/services/game/ops/logo-upload-complete","packages/core/services/game/ops/namespace-create","packages/core/services/game/ops/namespace-get","packages/core/services/game/ops/namespace-list","packages/core/services/game/ops/namespace-resolve-name-id","packages/core/services/game/ops/namespace-resolve-url","packages/core/services/game/ops/namespace-validate","packages/core/services/game/ops/namespace-version-history-list","packages/core/services/game/ops/namespace-version-set","packages/core/services/game/ops/recommend","packages/core/services/game/ops/resolve-name-id","packages/core/services/game/ops/resolve-namespace-id","packages/core/services/game/ops/token-development-validate","packages/core/services/game/ops/validate","packages/core/services/game/ops/version-create","packages/core/services/game/ops/version-get","packages/core/services/game/ops/version-list","packages/core/services/game/ops/version-validate","packages/core/services/ip/ops/info","packages/core/services/job-log/ops/read","packages/core/services/job-log/worker","packages/core/services/job-run","packages/core/services/job/standalone/gc","packages/core/services/job/util","packages/core/services/linode","packages/core/services/linode/standalone/gc","packages/core/services/load-test/standalone/api-cloud","packages/core/services/load-test/standalone/mm","packages/core/services/load-test/standalone/mm-sustain","packages/core/services/load-test/standalone/sqlx","packages/core/services/load-test/standalone/watch-requests","packages/core/services/mm-config/ops/game-get","packages/core/services/mm-config/ops/game-upsert","packages/core/services/mm-config/ops/lobby-group-get","packages/core/services/mm-config/ops/lobby-group-resolve-name-id","packages/core/services/mm-config/ops/lobby-group-resolve-version","packages/core/services/mm-config/ops/namespace-config-set","packages/core/services/mm-config/ops/namespace-config-validate","packages/core/services/mm-config/ops/namespace-create","packages/core/services/mm-config/ops/namespace-get","packages/core/services/mm-config/ops/version-get","packages/core/services/mm-config/ops/version-prepare","packages/core/services/mm-config/ops/version-publish","packages/core/services/mm/ops/dev-player-token-create","packages/core/services/mm/ops/lobby-find-fail","packages/core/services/mm/ops/lobby-find-lobby-query-list","packages/core/services/mm/ops/lobby-find-try-complete","packages/core/services/mm/ops/lobby-for-run-id","packages/core/services/mm/ops/lobby-get","packages/core/services/mm/ops/lobby-history","packages/core/services/mm/ops/lobby-idle-update","packages/core/services/mm/ops/lobby-list-for-namespace","packages/core/services/mm/ops/lobby-list-for-user-id","packages/core/services/mm/ops/lobby-player-count","packages/core/services/mm/ops/lobby-runtime-aggregate","packages/core/services/mm/ops/lobby-state-get","packages/core/services/mm/ops/player-count-for-namespace","packages/core/services/mm/ops/player-get","packages/core/services/mm/standalone/gc","packages/core/services/mm/util","packages/core/services/mm/worker","packages/core/services/monolith/standalone/worker","packages/core/services/monolith/standalone/workflow-worker","packages/core/services/nomad/standalone/monitor","packages/core/services/pegboard","packages/core/services/pegboard/standalone/dc-init","packages/core/services/pegboard/standalone/gc","packages/core/services/pegboard/standalone/metrics-publish","packages/core/services/pegboard/standalone/ws","packages/core/services/region/ops/get","packages/core/services/region/ops/list","packages/core/services/region/ops/list-for-game","packages/core/services/region/ops/recommend","packages/core/services/region/ops/resolve","packages/core/services/region/ops/resolve-for-game","packages/core/services/server-spec","packages/core/services/team-invite/ops/get","packages/core/services/team-invite/worker","packages/core/services/team/ops/avatar-upload-complete","packages/core/services/team/ops/get","packages/core/services/team/ops/join-request-list","packages/core/services/team/ops/member-count","packages/core/services/team/ops/member-get","packages/core/services/team/ops/member-list","packages/core/services/team/ops/member-relationship-get","packages/core/services/team/ops/profile-validate","packages/core/services/team/ops/recommend","packages/core/services/team/ops/resolve-display-name","packages/core/services/team/ops/user-ban-get","packages/core/services/team/ops/user-ban-list","packages/core/services/team/ops/validate","packages/core/services/team/util","packages/core/services/team/worker","packages/core/services/telemetry/standalone/beacon","packages/core/services/tier","packages/core/services/token/ops/create","packages/core/services/token/ops/exchange","packages/core/services/token/ops/get","packages/core/services/token/ops/revoke","packages/core/services/upload/ops/complete","packages/core/services/upload/ops/file-list","packages/core/services/upload/ops/get","packages/core/services/upload/ops/list-for-user","packages/core/services/upload/ops/prepare","packages/core/services/upload/worker","packages/core/services/user","packages/core/services/user-identity/ops/create","packages/core/services/user-identity/ops/delete","packages/core/services/user-identity/ops/get","packages/core/services/user/ops/avatar-upload-complete","packages/core/services/user/ops/get","packages/core/services/user/ops/pending-delete-toggle","packages/core/services/user/ops/profile-validate","packages/core/services/user/ops/resolve-email","packages/core/services/user/ops/team-list","packages/core/services/user/ops/token-create","packages/core/services/user/standalone/delete-pending","packages/core/services/user/worker","packages/edge/api/actor","packages/edge/api/intercom","packages/edge/api/monolith-edge","packages/edge/api/monolith-public","packages/edge/api/traefik-provider","packages/edge/infra/edge-server","packages/edge/services/ds","packages/edge/services/monolith/standalone/workflow-worker","packages/edge/services/pegboard","packages/edge/services/pegboard/standalone/ws","packages/toolchain/actors-sdk-embed","packages/toolchain/cli","packages/toolchain/js-utils-embed","packages/toolchain/toolchain","sdks/api/full/rust"]
[workspace.package]
version = "25.1.0-rc.1"
@@ -79,54 +79,6 @@ rev = "8a313913fa73d58f4f9532565b0084e723bc34ad"
git = "https://github.com/rivet-gg/deno"
rev = "9b1fbddb34c5e8cca115bc17a77c36f4c498eb4a"
-[workspace.dependencies.api-actor]
-path = "packages/api/actor"
-
-[workspace.dependencies.api-auth]
-path = "packages/api/auth"
-
-[workspace.dependencies.api-cf-verification]
-path = "packages/api/cf-verification"
-
-[workspace.dependencies.api-cloud]
-path = "packages/api/cloud"
-
-[workspace.dependencies.api-games]
-path = "packages/api/games"
-
-[workspace.dependencies.api-group]
-path = "packages/api/group"
-
-[workspace.dependencies.api-identity]
-path = "packages/api/identity"
-
-[workspace.dependencies.api-job]
-path = "packages/api/job"
-
-[workspace.dependencies.api-matchmaker]
-path = "packages/api/matchmaker"
-
-[workspace.dependencies.api-monolith-edge]
-path = "packages/api/monolith-edge"
-
-[workspace.dependencies.api-monolith-public]
-path = "packages/api/monolith-public"
-
-[workspace.dependencies.api-portal]
-path = "packages/api/portal"
-
-[workspace.dependencies.api-provision]
-path = "packages/api/provision"
-
-[workspace.dependencies.api-status]
-path = "packages/api/status"
-
-[workspace.dependencies.api-traefik-provider]
-path = "packages/api/traefik-provider"
-
-[workspace.dependencies.api-ui]
-path = "packages/api/ui"
-
[workspace.dependencies.api-helper]
path = "packages/common/api-helper/build"
@@ -339,668 +291,740 @@ path = "packages/common/util/search"
package = "rivet-util-search"
path = "packages/common/util/search"
+[workspace.dependencies.api-core-actor]
+path = "packages/core/api/actor"
+
+[workspace.dependencies.api-auth]
+path = "packages/core/api/auth"
+
+[workspace.dependencies.api-cf-verification]
+path = "packages/core/api/cf-verification"
+
+[workspace.dependencies.api-cloud]
+path = "packages/core/api/cloud"
+
+[workspace.dependencies.api-games]
+path = "packages/core/api/games"
+
+[workspace.dependencies.api-group]
+path = "packages/core/api/group"
+
+[workspace.dependencies.api-identity]
+path = "packages/core/api/identity"
+
+[workspace.dependencies.api-core-intercom]
+path = "packages/core/api/intercom"
+
+[workspace.dependencies.api-job]
+path = "packages/core/api/job"
+
+[workspace.dependencies.api-matchmaker]
+path = "packages/core/api/matchmaker"
+
+[workspace.dependencies.api-core-monolith-edge]
+path = "packages/core/api/monolith-edge"
+
+[workspace.dependencies.api-core-monolith-public]
+path = "packages/core/api/monolith-public"
+
+[workspace.dependencies.api-portal]
+path = "packages/core/api/portal"
+
+[workspace.dependencies.api-provision]
+path = "packages/core/api/provision"
+
+[workspace.dependencies.api-status]
+path = "packages/core/api/status"
+
+[workspace.dependencies.api-core-traefik-provider]
+path = "packages/core/api/traefik-provider"
+
+[workspace.dependencies.api-ui]
+path = "packages/core/api/ui"
+
[workspace.dependencies.pegboard-actor-kv]
-path = "packages/infra/client/actor-kv"
+path = "packages/core/infra/client/actor-kv"
[workspace.dependencies.pegboard-config]
-path = "packages/infra/client/config"
+path = "packages/core/infra/client/config"
[workspace.dependencies.pegboard-container-runner]
-path = "packages/infra/client/container-runner"
+path = "packages/core/infra/client/container-runner"
[workspace.dependencies.pegboard-echo-server]
-path = "packages/infra/client/echo"
+path = "packages/core/infra/client/echo"
[workspace.dependencies.pegboard-isolate-v8-runner]
-path = "packages/infra/client/isolate-v8-runner"
+path = "packages/core/infra/client/isolate-v8-runner"
[workspace.dependencies.pegboard-logs]
-path = "packages/infra/client/logs"
+path = "packages/core/infra/client/logs"
[workspace.dependencies.pegboard-manager]
-path = "packages/infra/client/manager"
-
-[workspace.dependencies.rivet-edge-server]
-path = "packages/infra/edge-server"
+path = "packages/core/infra/client/manager"
[workspace.dependencies.rivet-job-runner]
-path = "packages/infra/legacy/job-runner"
+path = "packages/core/infra/legacy/job-runner"
[workspace.dependencies.rivet-schema-generator]
-path = "packages/infra/schema-generator"
+path = "packages/core/infra/schema-generator"
[workspace.dependencies.rivet-server]
-path = "packages/infra/server"
+path = "packages/core/infra/server"
[workspace.dependencies.build]
-path = "packages/services/build"
+path = "packages/core/services/build"
[workspace.dependencies.build-create]
-path = "packages/services/build/ops/create"
+path = "packages/core/services/build/ops/create"
[workspace.dependencies.build-get]
-path = "packages/services/build/ops/get"
+path = "packages/core/services/build/ops/get"
[workspace.dependencies.build-list-for-env]
-path = "packages/services/build/ops/list-for-env"
+path = "packages/core/services/build/ops/list-for-env"
[workspace.dependencies.build-list-for-game]
-path = "packages/services/build/ops/list-for-game"
+path = "packages/core/services/build/ops/list-for-game"
[workspace.dependencies.build-default-create]
-path = "packages/services/build/standalone/default-create"
+path = "packages/core/services/build/standalone/default-create"
[workspace.dependencies.rivet-util-build]
-path = "packages/services/build/util"
+path = "packages/core/services/build/util"
[workspace.dependencies.util-build]
package = "rivet-util-build"
-path = "packages/services/build/util"
+path = "packages/core/services/build/util"
[workspace.dependencies.captcha-hcaptcha-config-get]
-path = "packages/services/captcha/ops/hcaptcha-config-get"
+path = "packages/core/services/captcha/ops/hcaptcha-config-get"
[workspace.dependencies.captcha-hcaptcha-verify]
-path = "packages/services/captcha/ops/hcaptcha-verify"
+path = "packages/core/services/captcha/ops/hcaptcha-verify"
[workspace.dependencies.captcha-request]
-path = "packages/services/captcha/ops/request"
+path = "packages/core/services/captcha/ops/request"
[workspace.dependencies.captcha-turnstile-config-get]
-path = "packages/services/captcha/ops/turnstile-config-get"
+path = "packages/core/services/captcha/ops/turnstile-config-get"
[workspace.dependencies.captcha-turnstile-verify]
-path = "packages/services/captcha/ops/turnstile-verify"
+path = "packages/core/services/captcha/ops/turnstile-verify"
[workspace.dependencies.captcha-verify]
-path = "packages/services/captcha/ops/verify"
+path = "packages/core/services/captcha/ops/verify"
[workspace.dependencies.rivet-util-captcha]
-path = "packages/services/captcha/util"
+path = "packages/core/services/captcha/util"
[workspace.dependencies.util-captcha]
package = "rivet-util-captcha"
-path = "packages/services/captcha/util"
+path = "packages/core/services/captcha/util"
[workspace.dependencies.cdn-namespace-auth-user-remove]
-path = "packages/services/cdn/ops/namespace-auth-user-remove"
+path = "packages/core/services/cdn/ops/namespace-auth-user-remove"
[workspace.dependencies.cdn-namespace-auth-user-update]
-path = "packages/services/cdn/ops/namespace-auth-user-update"
+path = "packages/core/services/cdn/ops/namespace-auth-user-update"
[workspace.dependencies.cdn-namespace-create]
-path = "packages/services/cdn/ops/namespace-create"
+path = "packages/core/services/cdn/ops/namespace-create"
[workspace.dependencies.cdn-namespace-domain-create]
-path = "packages/services/cdn/ops/namespace-domain-create"
+path = "packages/core/services/cdn/ops/namespace-domain-create"
[workspace.dependencies.cdn-namespace-domain-remove]
-path = "packages/services/cdn/ops/namespace-domain-remove"
+path = "packages/core/services/cdn/ops/namespace-domain-remove"
[workspace.dependencies.cdn-namespace-get]
-path = "packages/services/cdn/ops/namespace-get"
+path = "packages/core/services/cdn/ops/namespace-get"
[workspace.dependencies.cdn-namespace-resolve-domain]
-path = "packages/services/cdn/ops/namespace-resolve-domain"
+path = "packages/core/services/cdn/ops/namespace-resolve-domain"
[workspace.dependencies.cdn-ns-auth-type-set]
-path = "packages/services/cdn/ops/ns-auth-type-set"
+path = "packages/core/services/cdn/ops/ns-auth-type-set"
[workspace.dependencies.cdn-ns-enable-domain-public-auth-set]
-path = "packages/services/cdn/ops/ns-enable-domain-public-auth-set"
+path = "packages/core/services/cdn/ops/ns-enable-domain-public-auth-set"
[workspace.dependencies.cdn-site-create]
-path = "packages/services/cdn/ops/site-create"
+path = "packages/core/services/cdn/ops/site-create"
[workspace.dependencies.cdn-site-get]
-path = "packages/services/cdn/ops/site-get"
+path = "packages/core/services/cdn/ops/site-get"
[workspace.dependencies.cdn-site-list-for-game]
-path = "packages/services/cdn/ops/site-list-for-game"
+path = "packages/core/services/cdn/ops/site-list-for-game"
[workspace.dependencies.cdn-version-get]
-path = "packages/services/cdn/ops/version-get"
+path = "packages/core/services/cdn/ops/version-get"
[workspace.dependencies.cdn-version-prepare]
-path = "packages/services/cdn/ops/version-prepare"
+path = "packages/core/services/cdn/ops/version-prepare"
[workspace.dependencies.cdn-version-publish]
-path = "packages/services/cdn/ops/version-publish"
+path = "packages/core/services/cdn/ops/version-publish"
[workspace.dependencies.rivet-util-cdn]
-path = "packages/services/cdn/util"
+path = "packages/core/services/cdn/util"
[workspace.dependencies.util-cdn]
package = "rivet-util-cdn"
-path = "packages/services/cdn/util"
+path = "packages/core/services/cdn/util"
[workspace.dependencies.cdn-worker]
-path = "packages/services/cdn/worker"
+path = "packages/core/services/cdn/worker"
[workspace.dependencies.cf-custom-hostname-get]
-path = "packages/services/cf-custom-hostname/ops/get"
+path = "packages/core/services/cf-custom-hostname/ops/get"
[workspace.dependencies.cf-custom-hostname-list-for-namespace-id]
-path = "packages/services/cf-custom-hostname/ops/list-for-namespace-id"
+path = "packages/core/services/cf-custom-hostname/ops/list-for-namespace-id"
[workspace.dependencies.cf-custom-hostname-resolve-hostname]
-path = "packages/services/cf-custom-hostname/ops/resolve-hostname"
+path = "packages/core/services/cf-custom-hostname/ops/resolve-hostname"
[workspace.dependencies.cf-custom-hostname-worker]
-path = "packages/services/cf-custom-hostname/worker"
+path = "packages/core/services/cf-custom-hostname/worker"
[workspace.dependencies.cloud-device-link-create]
-path = "packages/services/cloud/ops/device-link-create"
+path = "packages/core/services/cloud/ops/device-link-create"
[workspace.dependencies.cloud-game-config-create]
-path = "packages/services/cloud/ops/game-config-create"
+path = "packages/core/services/cloud/ops/game-config-create"
[workspace.dependencies.cloud-game-config-get]
-path = "packages/services/cloud/ops/game-config-get"
+path = "packages/core/services/cloud/ops/game-config-get"
[workspace.dependencies.cloud-game-token-create]
-path = "packages/services/cloud/ops/game-token-create"
+path = "packages/core/services/cloud/ops/game-token-create"
[workspace.dependencies.cloud-namespace-create]
-path = "packages/services/cloud/ops/namespace-create"
+path = "packages/core/services/cloud/ops/namespace-create"
[workspace.dependencies.cloud-namespace-get]
-path = "packages/services/cloud/ops/namespace-get"
+path = "packages/core/services/cloud/ops/namespace-get"
[workspace.dependencies.cloud-namespace-token-development-create]
-path = "packages/services/cloud/ops/namespace-token-development-create"
+path = "packages/core/services/cloud/ops/namespace-token-development-create"
[workspace.dependencies.cloud-namespace-token-public-create]
-path = "packages/services/cloud/ops/namespace-token-public-create"
+path = "packages/core/services/cloud/ops/namespace-token-public-create"
[workspace.dependencies.cloud-version-get]
-path = "packages/services/cloud/ops/version-get"
+path = "packages/core/services/cloud/ops/version-get"
[workspace.dependencies.cloud-version-publish]
-path = "packages/services/cloud/ops/version-publish"
+path = "packages/core/services/cloud/ops/version-publish"
[workspace.dependencies.cloud-default-create]
-path = "packages/services/cloud/standalone/default-create"
+path = "packages/core/services/cloud/standalone/default-create"
[workspace.dependencies.cloud-worker]
-path = "packages/services/cloud/worker"
+path = "packages/core/services/cloud/worker"
[workspace.dependencies.cluster]
-path = "packages/services/cluster"
+path = "packages/core/services/cluster"
[workspace.dependencies.cluster-datacenter-tls-renew]
-path = "packages/services/cluster/standalone/datacenter-tls-renew"
+path = "packages/core/services/cluster/standalone/datacenter-tls-renew"
[workspace.dependencies.cluster-default-update]
-path = "packages/services/cluster/standalone/default-update"
+path = "packages/core/services/cluster/standalone/default-update"
[workspace.dependencies.cluster-gc]
-path = "packages/services/cluster/standalone/gc"
+path = "packages/core/services/cluster/standalone/gc"
[workspace.dependencies.cluster-metrics-publish]
-path = "packages/services/cluster/standalone/metrics-publish"
+path = "packages/core/services/cluster/standalone/metrics-publish"
[workspace.dependencies.custom-user-avatar-list-for-game]
-path = "packages/services/custom-user-avatar/ops/list-for-game"
+path = "packages/core/services/custom-user-avatar/ops/list-for-game"
[workspace.dependencies.custom-user-avatar-upload-complete]
-path = "packages/services/custom-user-avatar/ops/upload-complete"
+path = "packages/core/services/custom-user-avatar/ops/upload-complete"
[workspace.dependencies.debug-email-res]
-path = "packages/services/debug/ops/email-res"
+path = "packages/core/services/debug/ops/email-res"
[workspace.dependencies.ds]
-path = "packages/services/ds"
+path = "packages/core/services/ds"
[workspace.dependencies.ds-log-export]
-path = "packages/services/ds-log/ops/export"
+path = "packages/core/services/ds-log/ops/export"
[workspace.dependencies.ds-log-read]
-path = "packages/services/ds-log/ops/read"
+path = "packages/core/services/ds-log/ops/read"
[workspace.dependencies.dynamic-config]
-path = "packages/services/dynamic-config"
-
-[workspace.dependencies.edge-monolith-workflow-worker]
-path = "packages/services/edge/monolith/standalone/workflow-worker"
-
-[workspace.dependencies.edge-pegboard]
-path = "packages/services/edge/pegboard"
+path = "packages/core/services/dynamic-config"
[workspace.dependencies.email-verification-complete]
-path = "packages/services/email-verification/ops/complete"
+path = "packages/core/services/email-verification/ops/complete"
[workspace.dependencies.email-verification-create]
-path = "packages/services/email-verification/ops/create"
+path = "packages/core/services/email-verification/ops/create"
[workspace.dependencies.email-send]
-path = "packages/services/email/ops/send"
+path = "packages/core/services/email/ops/send"
[workspace.dependencies.external-request-validate]
-path = "packages/services/external/ops/request-validate"
+path = "packages/core/services/external/ops/request-validate"
[workspace.dependencies.external-worker]
-path = "packages/services/external/worker"
+path = "packages/core/services/external/worker"
[workspace.dependencies.faker-build]
-path = "packages/services/faker/ops/build"
+path = "packages/core/services/faker/ops/build"
[workspace.dependencies.faker-cdn-site]
-path = "packages/services/faker/ops/cdn-site"
+path = "packages/core/services/faker/ops/cdn-site"
[workspace.dependencies.faker-game]
-path = "packages/services/faker/ops/game"
+path = "packages/core/services/faker/ops/game"
[workspace.dependencies.faker-game-namespace]
-path = "packages/services/faker/ops/game-namespace"
+path = "packages/core/services/faker/ops/game-namespace"
[workspace.dependencies.faker-game-version]
-path = "packages/services/faker/ops/game-version"
+path = "packages/core/services/faker/ops/game-version"
[workspace.dependencies.faker-job-run]
-path = "packages/services/faker/ops/job-run"
+path = "packages/core/services/faker/ops/job-run"
[workspace.dependencies.faker-job-template]
-path = "packages/services/faker/ops/job-template"
+path = "packages/core/services/faker/ops/job-template"
[workspace.dependencies.faker-mm-lobby]
-path = "packages/services/faker/ops/mm-lobby"
+path = "packages/core/services/faker/ops/mm-lobby"
[workspace.dependencies.faker-mm-lobby-row]
-path = "packages/services/faker/ops/mm-lobby-row"
+path = "packages/core/services/faker/ops/mm-lobby-row"
[workspace.dependencies.faker-mm-player]
-path = "packages/services/faker/ops/mm-player"
+path = "packages/core/services/faker/ops/mm-player"
[workspace.dependencies.faker-region]
-path = "packages/services/faker/ops/region"
+path = "packages/core/services/faker/ops/region"
[workspace.dependencies.faker-team]
-path = "packages/services/faker/ops/team"
+path = "packages/core/services/faker/ops/team"
[workspace.dependencies.faker-user]
-path = "packages/services/faker/ops/user"
+path = "packages/core/services/faker/ops/user"
[workspace.dependencies.game-banner-upload-complete]
-path = "packages/services/game/ops/banner-upload-complete"
+path = "packages/core/services/game/ops/banner-upload-complete"
[workspace.dependencies.game-create]
-path = "packages/services/game/ops/create"
+path = "packages/core/services/game/ops/create"
[workspace.dependencies.game-get]
-path = "packages/services/game/ops/get"
+path = "packages/core/services/game/ops/get"
[workspace.dependencies.game-list-all]
-path = "packages/services/game/ops/list-all"
+path = "packages/core/services/game/ops/list-all"
[workspace.dependencies.game-list-for-team]
-path = "packages/services/game/ops/list-for-team"
+path = "packages/core/services/game/ops/list-for-team"
[workspace.dependencies.game-logo-upload-complete]
-path = "packages/services/game/ops/logo-upload-complete"
+path = "packages/core/services/game/ops/logo-upload-complete"
[workspace.dependencies.game-namespace-create]
-path = "packages/services/game/ops/namespace-create"
+path = "packages/core/services/game/ops/namespace-create"
[workspace.dependencies.game-namespace-get]
-path = "packages/services/game/ops/namespace-get"
+path = "packages/core/services/game/ops/namespace-get"
[workspace.dependencies.game-namespace-list]
-path = "packages/services/game/ops/namespace-list"
+path = "packages/core/services/game/ops/namespace-list"
[workspace.dependencies.game-namespace-resolve-name-id]
-path = "packages/services/game/ops/namespace-resolve-name-id"
+path = "packages/core/services/game/ops/namespace-resolve-name-id"
[workspace.dependencies.game-namespace-resolve-url]
-path = "packages/services/game/ops/namespace-resolve-url"
+path = "packages/core/services/game/ops/namespace-resolve-url"
[workspace.dependencies.game-namespace-validate]
-path = "packages/services/game/ops/namespace-validate"
+path = "packages/core/services/game/ops/namespace-validate"
[workspace.dependencies.game-namespace-version-history-list]
-path = "packages/services/game/ops/namespace-version-history-list"
+path = "packages/core/services/game/ops/namespace-version-history-list"
[workspace.dependencies.game-namespace-version-set]
-path = "packages/services/game/ops/namespace-version-set"
+path = "packages/core/services/game/ops/namespace-version-set"
[workspace.dependencies.game-recommend]
-path = "packages/services/game/ops/recommend"
+path = "packages/core/services/game/ops/recommend"
[workspace.dependencies.game-resolve-name-id]
-path = "packages/services/game/ops/resolve-name-id"
+path = "packages/core/services/game/ops/resolve-name-id"
[workspace.dependencies.game-resolve-namespace-id]
-path = "packages/services/game/ops/resolve-namespace-id"
+path = "packages/core/services/game/ops/resolve-namespace-id"
[workspace.dependencies.game-token-development-validate]
-path = "packages/services/game/ops/token-development-validate"
+path = "packages/core/services/game/ops/token-development-validate"
[workspace.dependencies.game-validate]
-path = "packages/services/game/ops/validate"
+path = "packages/core/services/game/ops/validate"
[workspace.dependencies.game-version-create]
-path = "packages/services/game/ops/version-create"
+path = "packages/core/services/game/ops/version-create"
[workspace.dependencies.game-version-get]
-path = "packages/services/game/ops/version-get"
+path = "packages/core/services/game/ops/version-get"
[workspace.dependencies.game-version-list]
-path = "packages/services/game/ops/version-list"
+path = "packages/core/services/game/ops/version-list"
[workspace.dependencies.game-version-validate]
-path = "packages/services/game/ops/version-validate"
+path = "packages/core/services/game/ops/version-validate"
[workspace.dependencies.ip-info]
-path = "packages/services/ip/ops/info"
+path = "packages/core/services/ip/ops/info"
[workspace.dependencies.job-log-read]
-path = "packages/services/job-log/ops/read"
+path = "packages/core/services/job-log/ops/read"
[workspace.dependencies.job-log-worker]
-path = "packages/services/job-log/worker"
+path = "packages/core/services/job-log/worker"
[workspace.dependencies.job-run]
-path = "packages/services/job-run"
+path = "packages/core/services/job-run"
[workspace.dependencies.job-gc]
-path = "packages/services/job/standalone/gc"
+path = "packages/core/services/job/standalone/gc"
[workspace.dependencies.rivet-util-job]
-path = "packages/services/job/util"
+path = "packages/core/services/job/util"
[workspace.dependencies.util-job]
package = "rivet-util-job"
-path = "packages/services/job/util"
+path = "packages/core/services/job/util"
[workspace.dependencies.linode]
-path = "packages/services/linode"
+path = "packages/core/services/linode"
[workspace.dependencies.linode-gc]
-path = "packages/services/linode/standalone/gc"
+path = "packages/core/services/linode/standalone/gc"
[workspace.dependencies.load-test-api-cloud]
-path = "packages/services/load-test/standalone/api-cloud"
+path = "packages/core/services/load-test/standalone/api-cloud"
[workspace.dependencies.load-test-mm]
-path = "packages/services/load-test/standalone/mm"
+path = "packages/core/services/load-test/standalone/mm"
[workspace.dependencies.load-test-mm-sustain]
-path = "packages/services/load-test/standalone/mm-sustain"
+path = "packages/core/services/load-test/standalone/mm-sustain"
[workspace.dependencies.load-test-sqlx]
-path = "packages/services/load-test/standalone/sqlx"
+path = "packages/core/services/load-test/standalone/sqlx"
[workspace.dependencies.load-test-watch-requests]
-path = "packages/services/load-test/standalone/watch-requests"
+path = "packages/core/services/load-test/standalone/watch-requests"
[workspace.dependencies.mm-config-game-get]
-path = "packages/services/mm-config/ops/game-get"
+path = "packages/core/services/mm-config/ops/game-get"
[workspace.dependencies.mm-config-game-upsert]
-path = "packages/services/mm-config/ops/game-upsert"
+path = "packages/core/services/mm-config/ops/game-upsert"
[workspace.dependencies.mm-config-lobby-group-get]
-path = "packages/services/mm-config/ops/lobby-group-get"
+path = "packages/core/services/mm-config/ops/lobby-group-get"
[workspace.dependencies.mm-config-lobby-group-resolve-name-id]
-path = "packages/services/mm-config/ops/lobby-group-resolve-name-id"
+path = "packages/core/services/mm-config/ops/lobby-group-resolve-name-id"
[workspace.dependencies.mm-config-lobby-group-resolve-version]
-path = "packages/services/mm-config/ops/lobby-group-resolve-version"
+path = "packages/core/services/mm-config/ops/lobby-group-resolve-version"
[workspace.dependencies.mm-config-namespace-config-set]
-path = "packages/services/mm-config/ops/namespace-config-set"
+path = "packages/core/services/mm-config/ops/namespace-config-set"
[workspace.dependencies.mm-config-namespace-config-validate]
-path = "packages/services/mm-config/ops/namespace-config-validate"
+path = "packages/core/services/mm-config/ops/namespace-config-validate"
[workspace.dependencies.mm-config-namespace-create]
-path = "packages/services/mm-config/ops/namespace-create"
+path = "packages/core/services/mm-config/ops/namespace-create"
[workspace.dependencies.mm-config-namespace-get]
-path = "packages/services/mm-config/ops/namespace-get"
+path = "packages/core/services/mm-config/ops/namespace-get"
[workspace.dependencies.mm-config-version-get]
-path = "packages/services/mm-config/ops/version-get"
+path = "packages/core/services/mm-config/ops/version-get"
[workspace.dependencies.mm-config-version-prepare]
-path = "packages/services/mm-config/ops/version-prepare"
+path = "packages/core/services/mm-config/ops/version-prepare"
[workspace.dependencies.mm-config-version-publish]
-path = "packages/services/mm-config/ops/version-publish"
+path = "packages/core/services/mm-config/ops/version-publish"
[workspace.dependencies.mm-dev-player-token-create]
-path = "packages/services/mm/ops/dev-player-token-create"
+path = "packages/core/services/mm/ops/dev-player-token-create"
[workspace.dependencies.mm-lobby-find-fail]
-path = "packages/services/mm/ops/lobby-find-fail"
+path = "packages/core/services/mm/ops/lobby-find-fail"
[workspace.dependencies.mm-lobby-find-lobby-query-list]
-path = "packages/services/mm/ops/lobby-find-lobby-query-list"
+path = "packages/core/services/mm/ops/lobby-find-lobby-query-list"
[workspace.dependencies.mm-lobby-find-try-complete]
-path = "packages/services/mm/ops/lobby-find-try-complete"
+path = "packages/core/services/mm/ops/lobby-find-try-complete"
[workspace.dependencies.mm-lobby-for-run-id]
-path = "packages/services/mm/ops/lobby-for-run-id"
+path = "packages/core/services/mm/ops/lobby-for-run-id"
[workspace.dependencies.mm-lobby-get]
-path = "packages/services/mm/ops/lobby-get"
+path = "packages/core/services/mm/ops/lobby-get"
[workspace.dependencies.mm-lobby-history]
-path = "packages/services/mm/ops/lobby-history"
+path = "packages/core/services/mm/ops/lobby-history"
[workspace.dependencies.mm-lobby-idle-update]
-path = "packages/services/mm/ops/lobby-idle-update"
+path = "packages/core/services/mm/ops/lobby-idle-update"
[workspace.dependencies.mm-lobby-list-for-namespace]
-path = "packages/services/mm/ops/lobby-list-for-namespace"
+path = "packages/core/services/mm/ops/lobby-list-for-namespace"
[workspace.dependencies.mm-lobby-list-for-user-id]
-path = "packages/services/mm/ops/lobby-list-for-user-id"
+path = "packages/core/services/mm/ops/lobby-list-for-user-id"
[workspace.dependencies.mm-lobby-player-count]
-path = "packages/services/mm/ops/lobby-player-count"
+path = "packages/core/services/mm/ops/lobby-player-count"
[workspace.dependencies.mm-lobby-runtime-aggregate]
-path = "packages/services/mm/ops/lobby-runtime-aggregate"
+path = "packages/core/services/mm/ops/lobby-runtime-aggregate"
[workspace.dependencies.mm-lobby-state-get]
-path = "packages/services/mm/ops/lobby-state-get"
+path = "packages/core/services/mm/ops/lobby-state-get"
[workspace.dependencies.mm-player-count-for-namespace]
-path = "packages/services/mm/ops/player-count-for-namespace"
+path = "packages/core/services/mm/ops/player-count-for-namespace"
[workspace.dependencies.mm-player-get]
-path = "packages/services/mm/ops/player-get"
+path = "packages/core/services/mm/ops/player-get"
[workspace.dependencies.mm-gc]
-path = "packages/services/mm/standalone/gc"
+path = "packages/core/services/mm/standalone/gc"
[workspace.dependencies.rivet-util-mm]
-path = "packages/services/mm/util"
+path = "packages/core/services/mm/util"
[workspace.dependencies.util-mm]
package = "rivet-util-mm"
-path = "packages/services/mm/util"
+path = "packages/core/services/mm/util"
[workspace.dependencies.mm-worker]
-path = "packages/services/mm/worker"
+path = "packages/core/services/mm/worker"
[workspace.dependencies.monolith-worker]
-path = "packages/services/monolith/standalone/worker"
+path = "packages/core/services/monolith/standalone/worker"
[workspace.dependencies.monolith-workflow-worker]
-path = "packages/services/monolith/standalone/workflow-worker"
+path = "packages/core/services/monolith/standalone/workflow-worker"
[workspace.dependencies.nomad-monitor]
-path = "packages/services/nomad/standalone/monitor"
+path = "packages/core/services/nomad/standalone/monitor"
[workspace.dependencies.pegboard]
-path = "packages/services/pegboard"
+path = "packages/core/services/pegboard"
[workspace.dependencies.pegboard-dc-init]
-path = "packages/services/pegboard/standalone/dc-init"
+path = "packages/core/services/pegboard/standalone/dc-init"
[workspace.dependencies.pegboard-gc]
-path = "packages/services/pegboard/standalone/gc"
+path = "packages/core/services/pegboard/standalone/gc"
[workspace.dependencies.pegboard-metrics-publish]
-path = "packages/services/pegboard/standalone/metrics-publish"
+path = "packages/core/services/pegboard/standalone/metrics-publish"
[workspace.dependencies.pegboard-ws]
-path = "packages/services/pegboard/standalone/ws"
+path = "packages/core/services/pegboard/standalone/ws"
[workspace.dependencies.region-get]
-path = "packages/services/region/ops/get"
+path = "packages/core/services/region/ops/get"
[workspace.dependencies.region-list]
-path = "packages/services/region/ops/list"
+path = "packages/core/services/region/ops/list"
[workspace.dependencies.region-list-for-game]
-path = "packages/services/region/ops/list-for-game"
+path = "packages/core/services/region/ops/list-for-game"
[workspace.dependencies.region-recommend]
-path = "packages/services/region/ops/recommend"
+path = "packages/core/services/region/ops/recommend"
[workspace.dependencies.region-resolve]
-path = "packages/services/region/ops/resolve"
+path = "packages/core/services/region/ops/resolve"
[workspace.dependencies.region-resolve-for-game]
-path = "packages/services/region/ops/resolve-for-game"
+path = "packages/core/services/region/ops/resolve-for-game"
[workspace.dependencies.server-spec]
-path = "packages/services/server-spec"
+path = "packages/core/services/server-spec"
[workspace.dependencies.team-invite-get]
-path = "packages/services/team-invite/ops/get"
+path = "packages/core/services/team-invite/ops/get"
[workspace.dependencies.team-invite-worker]
-path = "packages/services/team-invite/worker"
+path = "packages/core/services/team-invite/worker"
[workspace.dependencies.team-avatar-upload-complete]
-path = "packages/services/team/ops/avatar-upload-complete"
+path = "packages/core/services/team/ops/avatar-upload-complete"
[workspace.dependencies.team-get]
-path = "packages/services/team/ops/get"
+path = "packages/core/services/team/ops/get"
[workspace.dependencies.team-join-request-list]
-path = "packages/services/team/ops/join-request-list"
+path = "packages/core/services/team/ops/join-request-list"
[workspace.dependencies.team-member-count]
-path = "packages/services/team/ops/member-count"
+path = "packages/core/services/team/ops/member-count"
[workspace.dependencies.team-member-get]
-path = "packages/services/team/ops/member-get"
+path = "packages/core/services/team/ops/member-get"
[workspace.dependencies.team-member-list]
-path = "packages/services/team/ops/member-list"
+path = "packages/core/services/team/ops/member-list"
[workspace.dependencies.team-member-relationship-get]
-path = "packages/services/team/ops/member-relationship-get"
+path = "packages/core/services/team/ops/member-relationship-get"
[workspace.dependencies.team-profile-validate]
-path = "packages/services/team/ops/profile-validate"
+path = "packages/core/services/team/ops/profile-validate"
[workspace.dependencies.team-recommend]
-path = "packages/services/team/ops/recommend"
+path = "packages/core/services/team/ops/recommend"
[workspace.dependencies.team-resolve-display-name]
-path = "packages/services/team/ops/resolve-display-name"
+path = "packages/core/services/team/ops/resolve-display-name"
[workspace.dependencies.team-user-ban-get]
-path = "packages/services/team/ops/user-ban-get"
+path = "packages/core/services/team/ops/user-ban-get"
[workspace.dependencies.team-user-ban-list]
-path = "packages/services/team/ops/user-ban-list"
+path = "packages/core/services/team/ops/user-ban-list"
[workspace.dependencies.team-validate]
-path = "packages/services/team/ops/validate"
+path = "packages/core/services/team/ops/validate"
[workspace.dependencies.rivet-util-team]
-path = "packages/services/team/util"
+path = "packages/core/services/team/util"
[workspace.dependencies.util-team]
package = "rivet-util-team"
-path = "packages/services/team/util"
+path = "packages/core/services/team/util"
[workspace.dependencies.team-worker]
-path = "packages/services/team/worker"
+path = "packages/core/services/team/worker"
[workspace.dependencies.telemetry-beacon]
-path = "packages/services/telemetry/standalone/beacon"
+path = "packages/core/services/telemetry/standalone/beacon"
[workspace.dependencies.tier]
-path = "packages/services/tier"
+path = "packages/core/services/tier"
[workspace.dependencies.token-create]
-path = "packages/services/token/ops/create"
+path = "packages/core/services/token/ops/create"
[workspace.dependencies.token-exchange]
-path = "packages/services/token/ops/exchange"
+path = "packages/core/services/token/ops/exchange"
[workspace.dependencies.token-get]
-path = "packages/services/token/ops/get"
+path = "packages/core/services/token/ops/get"
[workspace.dependencies.token-revoke]
-path = "packages/services/token/ops/revoke"
+path = "packages/core/services/token/ops/revoke"
[workspace.dependencies.upload-complete]
-path = "packages/services/upload/ops/complete"
+path = "packages/core/services/upload/ops/complete"
[workspace.dependencies.upload-file-list]
-path = "packages/services/upload/ops/file-list"
+path = "packages/core/services/upload/ops/file-list"
[workspace.dependencies.upload-get]
-path = "packages/services/upload/ops/get"
+path = "packages/core/services/upload/ops/get"
[workspace.dependencies.upload-list-for-user]
-path = "packages/services/upload/ops/list-for-user"
+path = "packages/core/services/upload/ops/list-for-user"
[workspace.dependencies.upload-prepare]
-path = "packages/services/upload/ops/prepare"
+path = "packages/core/services/upload/ops/prepare"
[workspace.dependencies.upload-worker]
-path = "packages/services/upload/worker"
+path = "packages/core/services/upload/worker"
[workspace.dependencies.user]
-path = "packages/services/user"
+path = "packages/core/services/user"
[workspace.dependencies.user-identity-create]
-path = "packages/services/user-identity/ops/create"
+path = "packages/core/services/user-identity/ops/create"
[workspace.dependencies.user-identity-delete]
-path = "packages/services/user-identity/ops/delete"
+path = "packages/core/services/user-identity/ops/delete"
[workspace.dependencies.user-identity-get]
-path = "packages/services/user-identity/ops/get"
+path = "packages/core/services/user-identity/ops/get"
[workspace.dependencies.user-avatar-upload-complete]
-path = "packages/services/user/ops/avatar-upload-complete"
+path = "packages/core/services/user/ops/avatar-upload-complete"
[workspace.dependencies.user-get]
-path = "packages/services/user/ops/get"
+path = "packages/core/services/user/ops/get"
[workspace.dependencies.user-pending-delete-toggle]
-path = "packages/services/user/ops/pending-delete-toggle"
+path = "packages/core/services/user/ops/pending-delete-toggle"
[workspace.dependencies.user-profile-validate]
-path = "packages/services/user/ops/profile-validate"
+path = "packages/core/services/user/ops/profile-validate"
[workspace.dependencies.user-resolve-email]
-path = "packages/services/user/ops/resolve-email"
+path = "packages/core/services/user/ops/resolve-email"
[workspace.dependencies.user-team-list]
-path = "packages/services/user/ops/team-list"
+path = "packages/core/services/user/ops/team-list"
[workspace.dependencies.user-token-create]
-path = "packages/services/user/ops/token-create"
+path = "packages/core/services/user/ops/token-create"
[workspace.dependencies.user-delete-pending]
-path = "packages/services/user/standalone/delete-pending"
+path = "packages/core/services/user/standalone/delete-pending"
[workspace.dependencies.user-worker]
-path = "packages/services/user/worker"
+path = "packages/core/services/user/worker"
+
+[workspace.dependencies.api-edge-actor]
+path = "packages/edge/api/actor"
+
+[workspace.dependencies.api-edge-intercom]
+path = "packages/edge/api/intercom"
+
+[workspace.dependencies.api-edge-monolith-edge]
+path = "packages/edge/api/monolith-edge"
+
+[workspace.dependencies.api-edge-monolith-public]
+path = "packages/edge/api/monolith-public"
+
+[workspace.dependencies.api-edge-traefik-provider]
+path = "packages/edge/api/traefik-provider"
+
+[workspace.dependencies.rivet-edge-server]
+path = "packages/edge/infra/edge-server"
+
+[workspace.dependencies.edge-ds]
+path = "packages/edge/services/ds"
+
+[workspace.dependencies.edge-monolith-workflow-worker]
+path = "packages/edge/services/monolith/standalone/workflow-worker"
+
+[workspace.dependencies.edge-pegboard]
+path = "packages/edge/services/pegboard"
+
+[workspace.dependencies.edge-pegboard-ws]
+path = "packages/edge/services/pegboard/standalone/ws"
[workspace.dependencies.rivet-actors-sdk-embed]
path = "packages/toolchain/actors-sdk-embed"
diff --git a/docker/dev-full/rivet-edge-server/config.yaml b/docker/dev-full/rivet-edge-server/config.yaml
new file mode 100644
index 0000000000..0b110e00c4
--- /dev/null
+++ b/docker/dev-full/rivet-edge-server/config.yaml
@@ -0,0 +1,69 @@
+server:
+ rivet:
+ auth:
+ access_kind: development
+
+ ui:
+ public_origin_regex: .*
+
+ guard:
+ # TLS not configured for local development
+ tls_enabled: false
+ # Corresponds to the ports configured in the `docker-compose.yml`
+ http_port: 7080
+ https_port: 7443
+ min_ingress_port_tcp: 7500
+ max_ingress_port_tcp: 7599
+ min_ingress_port_udp: 7500
+ max_ingress_port_udp: 7599
+
+ # Enable status checks if testing status check project
+ status:
+ token: local
+ system_test_isolate_project: default
+ system_test_isolate_environment: default
+ cockroachdb:
+ url: postgresql://cockroachdb:26257/defaultdb?sslmode=disable
+ username: root
+ redis:
+ ephemeral:
+ url: redis://redis:6379
+ password: password
+ persistent:
+ url: redis://redis:6379
+ password: password
+ clickhouse:
+ http_url: http://clickhouse:8123
+ native_url: clickhouse://clickhouse:9000
+ username: default
+ password: default
+ provision_users:
+ vector:
+ username: vector
+ password: vector
+ role: write
+ s3:
+ region: us-east-1
+ endpoint_internal: http://seaweedfs:9000
+ endpoint_edge_internal: http://seaweedfs:9000
+ endpoint_external: http://127.0.0.1:9000
+ access_key_id: admin
+ secret_access_key: admin
+ nats:
+ urls:
+ - nats://nats:4222
+
+ # IMPORTANT:
+ # - Generate your own JWT tokens before shipping to production as seen in the
+ # self-hosting documentation.
+ # - Do not include the private key in this file. Instead, use the env var
+ # `RIVET__SERVER__JWT__PRIVATE`.
+ jwt:
+ public: |
+ -----BEGIN PUBLIC KEY-----
+ MCowBQYDK2VwAyEAx7S9ab9ErA50y0tVfFro919+BBxFSuwMKmcJ5QI853Y=
+ -----END PUBLIC KEY-----
+ private: |
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIDI+WHFytxvdtfGot36NMCI26s2Yp0+E5u9OiPf3NQX3
+ -----END PRIVATE KEY-----
diff --git a/docker/dev-full/rivet-server/config.yaml b/docker/dev-full/rivet-server/config.yaml
index 0b110e00c4..5826b3f891 100644
--- a/docker/dev-full/rivet-server/config.yaml
+++ b/docker/dev-full/rivet-server/config.yaml
@@ -1,27 +1,10 @@
server:
rivet:
- auth:
- access_kind: development
-
- ui:
- public_origin_regex: .*
-
- guard:
- # TLS not configured for local development
- tls_enabled: false
- # Corresponds to the ports configured in the `docker-compose.yml`
- http_port: 7080
- https_port: 7443
- min_ingress_port_tcp: 7500
- max_ingress_port_tcp: 7599
- min_ingress_port_udp: 7500
- max_ingress_port_udp: 7599
-
- # Enable status checks if testing status check project
- status:
- token: local
- system_test_isolate_project: default
- system_test_isolate_environment: default
+ edge:
+ # TODO:
+ cluster_id: f288913c-735d-4188-bf9b-2fcf6eac7b9c
+ datacenter_id: f288913c-735d-4188-bf9b-2fcf6eac7b9c
+ server_token: foo
cockroachdb:
url: postgresql://cockroachdb:26257/defaultdb?sslmode=disable
username: root
diff --git a/docker/test/clickhouse/config.xml b/docker/test/clickhouse/config.xml
new file mode 100644
index 0000000000..5d716f5468
--- /dev/null
+++ b/docker/test/clickhouse/config.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+ localhost
+ 9181
+
+
+
+
+
+ 9181
+ 1
+ /var/lib/clickhouse/coordination/log
+ /var/lib/clickhouse/coordination/snapshots
+
+
+ 10000
+ 30000
+ warning
+
+
+
+
+ 1
+ localhost
+ 9234
+
+
+
+
+
+ /clickhouse/tables/{shard}/{database}/{table}
+ {replica}
+
+
+
+ cluster1
+ replica1
+ 01
+
+
diff --git a/docker/test/clickhouse/users.xml b/docker/test/clickhouse/users.xml
new file mode 100644
index 0000000000..5cc16cef4d
--- /dev/null
+++ b/docker/test/clickhouse/users.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+ 1
+
+
+ default
+
+
+ default
+
+ ::/0
+
+
+
+ default
+
+
+ 1
+ 1
+ 1
+
+
+
+ .*
+
+
+
+
+
+
+
+ 10000000000
+ 300
+ 1000000000
+
+
+
+
+
+
+
+ 3600
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
diff --git a/docker/test/docker-compose.yml b/docker/test/docker-compose.yml
new file mode 100644
index 0000000000..5f08b1db5b
--- /dev/null
+++ b/docker/test/docker-compose.yml
@@ -0,0 +1,297 @@
+services:
+ rivet-server:
+ build:
+ context: ../..
+ dockerfile: docker/universal/Dockerfile
+ target: server-full
+ platform: linux/amd64
+ restart: unless-stopped
+ command: /usr/bin/rivet-server start
+ environment:
+ - RUST_BACKTRACE=1
+ - RUST_LOG=debug,hyper=info
+ - RUST_LOG_TARGET=1
+ - RUST_LOG_SPAN_PATH=1
+ stop_grace_period: 0s
+ ports:
+ # API
+ - "8080:8080"
+ # API edge
+ - "8081:8081"
+ # Pegboard
+ - "8082:8082"
+ depends_on:
+ cockroachdb:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+ clickhouse:
+ condition: service_healthy
+ nats:
+ condition: service_healthy
+ seaweedfs:
+ condition: service_healthy
+ vector-server:
+ condition: service_started
+ volumes:
+ - ./rivet-server:/etc/rivet-server:ro
+ networks:
+ - rivet-network
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:8090/health/liveness"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+
+ rivet-edge-server:
+ build:
+ context: ../..
+ dockerfile: docker/universal/Dockerfile
+ target: edge-server
+ platform: linux/amd64
+ restart: unless-stopped
+ command: /usr/bin/rivet-edge-server start
+ environment:
+ - RUST_BACKTRACE=1
+ - RUST_LOG=debug,hyper=info
+ - RUST_LOG_TARGET=1
+ - RUST_LOG_SPAN_PATH=1
+ - RUST_LOG_ANSI_COLOR=1
+ stop_grace_period: 0s
+ ports:
+ # API
+ - "8083:8080"
+ depends_on:
+ rivet-server:
+ condition: service_healthy
+ cockroachdb:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+ nats:
+ condition: service_healthy
+ seaweedfs:
+ condition: service_healthy
+ vector-server:
+ condition: service_started
+ volumes:
+ - ./rivet-edge-server:/etc/rivet-server:ro
+ - sqlite-data:/var/lib/rivet-sqlite:rw
+ networks:
+ - rivet-network
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:8090/health/liveness"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+
+ rivet-shell:
+ build:
+ context: ../..
+ dockerfile: docker/universal/Dockerfile
+ target: server-full
+ platform: linux/amd64
+ restart: unless-stopped
+ command: sleep infinity
+ environment:
+ - RUST_BACKTRACE=1
+ stop_grace_period: 0s
+ volumes:
+ - ./rivet-server:/etc/rivet-server:ro
+ networks:
+ - rivet-network
+
+ # rivet-guard:
+ # restart: unless-stopped
+ # image: traefik:v3.2.1
+ # command: --configFile=/etc/rivet-guard/traefik.yaml
+ # volumes:
+ # - ./rivet-guard:/etc/rivet-guard:ro
+ # ports:
+ # # HTTP
+ # - "7080:7080"
+ # # HTTPS
+ # - "7443:7443"
+ # # Dashboard
+ # - "9980:9980"
+ # # Enable TCP & UDP port ranges.
+ # #
+ # # Corresponds to `server.rivet.guard.min_ingress_port_tcp` and
+ # # `actor.network.wan_port_range_max` in `rivet-server/config.yaml`.
+ # #
+ # # We only reserve 100 ports instead of the default 22,000 since each
+ # # individual port converts to an iptable rule when using Docker, which
+ # # can cause unexpected side effects. This limits the number of actors
+ # # using host networking to 100.
+ # - "7500-7599:7500-7599"
+ # depends_on:
+ # rivet-server:
+ # condition: service_healthy
+ # networks:
+ # - rivet-network
+
+ cockroachdb:
+ restart: unless-stopped
+ image: cockroachdb/cockroach:v24.2.3
+ command: start-single-node --insecure
+ volumes:
+ - cockroach-data:/cockroach/cockroach-data
+ networks:
+ - rivet-network
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:8080/health?ready=1"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+
+ rivet-client:
+ build:
+ context: ../..
+ dockerfile: docker/universal/Dockerfile
+ target: client-full
+ # TODO(RVT-4168): Compile libfdb from scratch for ARM
+ platform: linux/amd64
+ restart: unless-stopped
+ command: -c /etc/rivet-client/config.yaml
+ environment:
+ - RUST_BACKTRACE=1
+ stop_grace_period: 0s
+ depends_on:
+ rivet-edge-server:
+ condition: service_healthy
+ foundationdb:
+ condition: service_healthy
+ volumes:
+ - ./rivet-client:/etc/rivet-client:ro
+ - client-data:/var/lib/rivet-client
+ ports:
+ # Enable host networking for actors
+ #
+ # Corresponds to `actor.network.wan_port_range_min` and
+ # `actor.network.wan_port_range_max` in `rivet-client/config.yaml`.
+ #
+ # We only reserve 100 ports instead of the default 22,000. See
+ # rivet-guard for explanation.
+ - "7600-7699:7600-7699"
+ networks:
+ - rivet-network
+
+ redis:
+ restart: unless-stopped
+ image: bitnami/valkey:8.0.1
+ # TODO: Remove root user
+ user: root
+ volumes:
+ - redis-data:/data
+ command: redis-server --requirepass password --save 60 1 --appendonly yes
+ networks:
+ - rivet-network
+ healthcheck:
+ test: ["CMD", "redis-cli", "ping"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+
+ clickhouse:
+ restart: unless-stopped
+ image: clickhouse/clickhouse-server:23.10.1
+ volumes:
+ - clickhouse-data:/var/lib/clickhouse
+ - ./clickhouse/config.xml:/etc/clickhouse-server/config.d/config.xml
+ - ./clickhouse/users.xml:/etc/clickhouse-server/users.d/users.xml
+ networks:
+ - rivet-network
+ healthcheck:
+ test: ["CMD", "clickhouse-client", "--password", "default", "--query", "SELECT 1"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+
+ nats:
+ restart: unless-stopped
+ image: nats:2.10.22-scratch
+ networks:
+ - rivet-network
+ healthcheck:
+ test: ["CMD", "nats-server", "--health"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+
+ seaweedfs:
+ restart: unless-stopped
+ image: chrislusf/seaweedfs:3.79
+ # TODO: Remove root user
+ user: root
+ # `raftHashicorp` speeds up initial leader election
+ command: |
+ server \
+ -dir /var/lib/seaweedfs \
+ -master.raftBootstrap -master.raftHashicorp \
+ -s3 -s3.config /etc/seaweedfs/s3.json -s3.port=9000 -s3.allowEmptyFolder=false -s3.allowDeleteBucketNotEmpty=false
+ volumes:
+ - ./seaweedfs:/etc/seaweedfs:ro
+ - seaweedfs-data:/var/lib/seaweedfs
+ ports:
+ # S3
+ - "9000:9000"
+ networks:
+ - rivet-network
+ healthcheck:
+ test: ["CMD", "nc", "-z", "127.0.0.1", "9000"]
+ interval: 2s
+ timeout: 10s
+
+ foundationdb:
+ restart: unless-stopped
+ # See docs-internal/infrastructure/fdb/AVX.md
+ image: foundationdb/foundationdb:7.1.60
+ platform: linux/amd64
+ entrypoint: ["/usr/bin/tini", "-g", "--", "/usr/local/bin/entrypoint.sh"]
+ volumes:
+ - ./foundationdb/entrypoint.sh:/usr/local/bin/entrypoint.sh
+ - foundationdb-data:/var/fdb:rw
+ - foundationdb-storage-data:/var/fdb/data:rw
+ healthcheck:
+ test: ["CMD", "fdbcli", "--exec", "status"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+ networks:
+ - rivet-network
+
+ vector-client:
+ restart: unless-stopped
+ image: timberio/vector:0.42.0-distroless-static
+ command: -C /etc/vector
+ volumes:
+ - ./vector-client:/etc/vector
+ # Mount client data to read logs
+ - client-data:/var/lib/rivet-client
+ networks:
+ - rivet-network
+
+ vector-server:
+ restart: unless-stopped
+ image: timberio/vector:0.42.0-distroless-static
+ command: -C /etc/vector
+ volumes:
+ - vector-server-data:/var/lib/vector
+ - ./vector-server:/etc/vector
+ networks:
+ - rivet-network
+
+networks:
+ rivet-network:
+ driver: bridge
+
+volumes:
+ client-data:
+ cockroach-data:
+ redis-data:
+ clickhouse-data:
+ seaweedfs-data:
+ vector-server-data:
+ foundationdb-data:
+ foundationdb-storage-data:
+ sqlite-data:
diff --git a/docker/test/foundationdb/entrypoint.sh b/docker/test/foundationdb/entrypoint.sh
new file mode 100755
index 0000000000..9336a40029
--- /dev/null
+++ b/docker/test/foundationdb/entrypoint.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+function configure_database() {
+ echo "Configuring database..."
+ until fdbcli --exec 'configure new single ssd' --timeout 10; do
+ sleep 2
+ done
+ echo "Database configured."
+}
+
+# Background process will wait until FoundationDB is up and configure it.
+if [ ! -e /var/fdb/fdb.cluster ]; then
+ configure_database &
+else
+ echo "Database already configured."
+fi
+
+# This will automatically populate the file contents with `docker:docker@$PUBLIC_IP:$FDB_PORT`
+export FDB_NETWORKING_MODE=container
+exec /var/fdb/scripts/fdb.bash "$@"
diff --git a/docker/test/rivet-client/config.yaml b/docker/test/rivet-client/config.yaml
new file mode 100644
index 0000000000..8165fcb6aa
--- /dev/null
+++ b/docker/test/rivet-client/config.yaml
@@ -0,0 +1,36 @@
+client:
+ runner:
+ flavor: isolate
+ # Enables running in non-privileged Docker containers
+ use_mounts: false
+ cluster:
+ # This is safe to hardcode
+ client_id: fc67e54e-5d6a-4726-ab23-77b0e54f068f
+ # This is hardcoded to match the value in rivet-edge-server/config.yaml
+ datacenter_id: f288913c-735d-4188-bf9b-2fcf6eac7b9c
+ api_endpoint: http://rivet-edge-server:8080
+ pegboard_endpoint: ws://rivet-edge-server:8082
+ network:
+ bind_ip: 127.0.0.1
+ # Point to DNS name inside Docker container
+ lan_hostname: rivet-client
+ # Point to localhost since this is a dev instance
+ wan_hostname: 127.0.0.1
+ # Corresponds to the port range configured in the `docker-compose.yml`
+ wan_port_range_min: 7600
+ wan_port_range_max: 7699
+ cni:
+ network_interface: eth0
+ # Don't reserve any resources on dev instances
+ reserved_resources:
+ cpu: 0
+ memory: 0
+ logs:
+ redirect_logs: true
+ foundationdb:
+ cluster_description: docker
+ cluster_id: docker
+ addresses: !static
+ - "foundationdb:4500"
+ vector:
+ address: vector-server:6100
diff --git a/docker/test/rivet-edge-server/config.yaml b/docker/test/rivet-edge-server/config.yaml
new file mode 100644
index 0000000000..269eebfeb9
--- /dev/null
+++ b/docker/test/rivet-edge-server/config.yaml
@@ -0,0 +1,74 @@
+server:
+ rivet:
+ auth:
+ access_kind: development
+
+ edge:
+ # TODO:
+ cluster_id: f288913c-735d-4188-bf9b-2fcf6eac7b9c
+ datacenter_id: f288913c-735d-4188-bf9b-2fcf6eac7b9c
+ intercom_endpoint: http://rivet-server:8081
+
+ guard:
+ # TLS not configured for local development
+ tls_enabled: false
+ # Corresponds to the ports configured in the `docker-compose.yml`
+ http_port: 7080
+ https_port: 7443
+ min_ingress_port_tcp: 7500
+ max_ingress_port_tcp: 7599
+ min_ingress_port_udp: 7500
+ max_ingress_port_udp: 7599
+
+ # Enable status checks if testing status check project
+ status:
+ token: local
+ system_test_isolate_project: default
+ system_test_isolate_environment: default
+ foundationdb:
+ connection: docker:docker@foundationdb:4500
+ cockroachdb:
+ url: postgresql://cockroachdb:26257/defaultdb?sslmode=disable
+ username: root
+ redis:
+ ephemeral:
+ url: redis://redis:6379
+ password: password
+ persistent:
+ url: redis://redis:6379
+ password: password
+ clickhouse:
+ http_url: http://clickhouse:8123
+ native_url: clickhouse://clickhouse:9000
+ username: default
+ password: default
+ provision_users:
+ vector:
+ username: vector
+ password: vector
+ role: write
+ s3:
+ region: us-east-1
+ endpoint_internal: http://seaweedfs:9000
+ endpoint_edge_internal: http://seaweedfs:9000
+ endpoint_external: http://127.0.0.1:9000
+ access_key_id: admin
+ secret_access_key: admin
+ nats:
+ urls:
+ - nats://nats:4222
+
+ # IMPORTANT:
+ # - Generate your own JWT tokens before shipping to production as seen in the
+ # self-hosting documentation.
+ # - Do not include the private key in this file. Instead, use the env var
+ # `RIVET__SERVER__JWT__PRIVATE`.
+ jwt:
+ public: |
+ -----BEGIN PUBLIC KEY-----
+ MCowBQYDK2VwAyEAx7S9ab9ErA50y0tVfFro919+BBxFSuwMKmcJ5QI853Y=
+ -----END PUBLIC KEY-----
+ private: |
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIDI+WHFytxvdtfGot36NMCI26s2Yp0+E5u9OiPf3NQX3
+ -----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/docker/test/rivet-guard/traefik.yaml b/docker/test/rivet-guard/traefik.yaml
new file mode 100644
index 0000000000..610b9b918e
--- /dev/null
+++ b/docker/test/rivet-guard/traefik.yaml
@@ -0,0 +1,1122 @@
+# DO NOT MODIFY
+#
+# Generated with scripts/docker/generate_configs.ts
+
+entryPoints:
+ traefik:
+ address: ':9980'
+ lb-7080:
+ address: ':7080'
+ lb-7443:
+ address: ':7443'
+ lb-7500-tcp:
+ address: ':7500/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7500-udp:
+ address: ':7500/udp'
+ udp:
+ timeout: 15s
+ lb-7501-tcp:
+ address: ':7501/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7501-udp:
+ address: ':7501/udp'
+ udp:
+ timeout: 15s
+ lb-7502-tcp:
+ address: ':7502/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7502-udp:
+ address: ':7502/udp'
+ udp:
+ timeout: 15s
+ lb-7503-tcp:
+ address: ':7503/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7503-udp:
+ address: ':7503/udp'
+ udp:
+ timeout: 15s
+ lb-7504-tcp:
+ address: ':7504/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7504-udp:
+ address: ':7504/udp'
+ udp:
+ timeout: 15s
+ lb-7505-tcp:
+ address: ':7505/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7505-udp:
+ address: ':7505/udp'
+ udp:
+ timeout: 15s
+ lb-7506-tcp:
+ address: ':7506/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7506-udp:
+ address: ':7506/udp'
+ udp:
+ timeout: 15s
+ lb-7507-tcp:
+ address: ':7507/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7507-udp:
+ address: ':7507/udp'
+ udp:
+ timeout: 15s
+ lb-7508-tcp:
+ address: ':7508/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7508-udp:
+ address: ':7508/udp'
+ udp:
+ timeout: 15s
+ lb-7509-tcp:
+ address: ':7509/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7509-udp:
+ address: ':7509/udp'
+ udp:
+ timeout: 15s
+ lb-7510-tcp:
+ address: ':7510/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7510-udp:
+ address: ':7510/udp'
+ udp:
+ timeout: 15s
+ lb-7511-tcp:
+ address: ':7511/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7511-udp:
+ address: ':7511/udp'
+ udp:
+ timeout: 15s
+ lb-7512-tcp:
+ address: ':7512/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7512-udp:
+ address: ':7512/udp'
+ udp:
+ timeout: 15s
+ lb-7513-tcp:
+ address: ':7513/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7513-udp:
+ address: ':7513/udp'
+ udp:
+ timeout: 15s
+ lb-7514-tcp:
+ address: ':7514/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7514-udp:
+ address: ':7514/udp'
+ udp:
+ timeout: 15s
+ lb-7515-tcp:
+ address: ':7515/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7515-udp:
+ address: ':7515/udp'
+ udp:
+ timeout: 15s
+ lb-7516-tcp:
+ address: ':7516/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7516-udp:
+ address: ':7516/udp'
+ udp:
+ timeout: 15s
+ lb-7517-tcp:
+ address: ':7517/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7517-udp:
+ address: ':7517/udp'
+ udp:
+ timeout: 15s
+ lb-7518-tcp:
+ address: ':7518/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7518-udp:
+ address: ':7518/udp'
+ udp:
+ timeout: 15s
+ lb-7519-tcp:
+ address: ':7519/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7519-udp:
+ address: ':7519/udp'
+ udp:
+ timeout: 15s
+ lb-7520-tcp:
+ address: ':7520/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7520-udp:
+ address: ':7520/udp'
+ udp:
+ timeout: 15s
+ lb-7521-tcp:
+ address: ':7521/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7521-udp:
+ address: ':7521/udp'
+ udp:
+ timeout: 15s
+ lb-7522-tcp:
+ address: ':7522/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7522-udp:
+ address: ':7522/udp'
+ udp:
+ timeout: 15s
+ lb-7523-tcp:
+ address: ':7523/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7523-udp:
+ address: ':7523/udp'
+ udp:
+ timeout: 15s
+ lb-7524-tcp:
+ address: ':7524/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7524-udp:
+ address: ':7524/udp'
+ udp:
+ timeout: 15s
+ lb-7525-tcp:
+ address: ':7525/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7525-udp:
+ address: ':7525/udp'
+ udp:
+ timeout: 15s
+ lb-7526-tcp:
+ address: ':7526/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7526-udp:
+ address: ':7526/udp'
+ udp:
+ timeout: 15s
+ lb-7527-tcp:
+ address: ':7527/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7527-udp:
+ address: ':7527/udp'
+ udp:
+ timeout: 15s
+ lb-7528-tcp:
+ address: ':7528/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7528-udp:
+ address: ':7528/udp'
+ udp:
+ timeout: 15s
+ lb-7529-tcp:
+ address: ':7529/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7529-udp:
+ address: ':7529/udp'
+ udp:
+ timeout: 15s
+ lb-7530-tcp:
+ address: ':7530/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7530-udp:
+ address: ':7530/udp'
+ udp:
+ timeout: 15s
+ lb-7531-tcp:
+ address: ':7531/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7531-udp:
+ address: ':7531/udp'
+ udp:
+ timeout: 15s
+ lb-7532-tcp:
+ address: ':7532/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7532-udp:
+ address: ':7532/udp'
+ udp:
+ timeout: 15s
+ lb-7533-tcp:
+ address: ':7533/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7533-udp:
+ address: ':7533/udp'
+ udp:
+ timeout: 15s
+ lb-7534-tcp:
+ address: ':7534/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7534-udp:
+ address: ':7534/udp'
+ udp:
+ timeout: 15s
+ lb-7535-tcp:
+ address: ':7535/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7535-udp:
+ address: ':7535/udp'
+ udp:
+ timeout: 15s
+ lb-7536-tcp:
+ address: ':7536/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7536-udp:
+ address: ':7536/udp'
+ udp:
+ timeout: 15s
+ lb-7537-tcp:
+ address: ':7537/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7537-udp:
+ address: ':7537/udp'
+ udp:
+ timeout: 15s
+ lb-7538-tcp:
+ address: ':7538/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7538-udp:
+ address: ':7538/udp'
+ udp:
+ timeout: 15s
+ lb-7539-tcp:
+ address: ':7539/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7539-udp:
+ address: ':7539/udp'
+ udp:
+ timeout: 15s
+ lb-7540-tcp:
+ address: ':7540/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7540-udp:
+ address: ':7540/udp'
+ udp:
+ timeout: 15s
+ lb-7541-tcp:
+ address: ':7541/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7541-udp:
+ address: ':7541/udp'
+ udp:
+ timeout: 15s
+ lb-7542-tcp:
+ address: ':7542/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7542-udp:
+ address: ':7542/udp'
+ udp:
+ timeout: 15s
+ lb-7543-tcp:
+ address: ':7543/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7543-udp:
+ address: ':7543/udp'
+ udp:
+ timeout: 15s
+ lb-7544-tcp:
+ address: ':7544/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7544-udp:
+ address: ':7544/udp'
+ udp:
+ timeout: 15s
+ lb-7545-tcp:
+ address: ':7545/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7545-udp:
+ address: ':7545/udp'
+ udp:
+ timeout: 15s
+ lb-7546-tcp:
+ address: ':7546/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7546-udp:
+ address: ':7546/udp'
+ udp:
+ timeout: 15s
+ lb-7547-tcp:
+ address: ':7547/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7547-udp:
+ address: ':7547/udp'
+ udp:
+ timeout: 15s
+ lb-7548-tcp:
+ address: ':7548/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7548-udp:
+ address: ':7548/udp'
+ udp:
+ timeout: 15s
+ lb-7549-tcp:
+ address: ':7549/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7549-udp:
+ address: ':7549/udp'
+ udp:
+ timeout: 15s
+ lb-7550-tcp:
+ address: ':7550/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7550-udp:
+ address: ':7550/udp'
+ udp:
+ timeout: 15s
+ lb-7551-tcp:
+ address: ':7551/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7551-udp:
+ address: ':7551/udp'
+ udp:
+ timeout: 15s
+ lb-7552-tcp:
+ address: ':7552/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7552-udp:
+ address: ':7552/udp'
+ udp:
+ timeout: 15s
+ lb-7553-tcp:
+ address: ':7553/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7553-udp:
+ address: ':7553/udp'
+ udp:
+ timeout: 15s
+ lb-7554-tcp:
+ address: ':7554/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7554-udp:
+ address: ':7554/udp'
+ udp:
+ timeout: 15s
+ lb-7555-tcp:
+ address: ':7555/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7555-udp:
+ address: ':7555/udp'
+ udp:
+ timeout: 15s
+ lb-7556-tcp:
+ address: ':7556/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7556-udp:
+ address: ':7556/udp'
+ udp:
+ timeout: 15s
+ lb-7557-tcp:
+ address: ':7557/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7557-udp:
+ address: ':7557/udp'
+ udp:
+ timeout: 15s
+ lb-7558-tcp:
+ address: ':7558/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7558-udp:
+ address: ':7558/udp'
+ udp:
+ timeout: 15s
+ lb-7559-tcp:
+ address: ':7559/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7559-udp:
+ address: ':7559/udp'
+ udp:
+ timeout: 15s
+ lb-7560-tcp:
+ address: ':7560/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7560-udp:
+ address: ':7560/udp'
+ udp:
+ timeout: 15s
+ lb-7561-tcp:
+ address: ':7561/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7561-udp:
+ address: ':7561/udp'
+ udp:
+ timeout: 15s
+ lb-7562-tcp:
+ address: ':7562/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7562-udp:
+ address: ':7562/udp'
+ udp:
+ timeout: 15s
+ lb-7563-tcp:
+ address: ':7563/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7563-udp:
+ address: ':7563/udp'
+ udp:
+ timeout: 15s
+ lb-7564-tcp:
+ address: ':7564/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7564-udp:
+ address: ':7564/udp'
+ udp:
+ timeout: 15s
+ lb-7565-tcp:
+ address: ':7565/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7565-udp:
+ address: ':7565/udp'
+ udp:
+ timeout: 15s
+ lb-7566-tcp:
+ address: ':7566/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7566-udp:
+ address: ':7566/udp'
+ udp:
+ timeout: 15s
+ lb-7567-tcp:
+ address: ':7567/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7567-udp:
+ address: ':7567/udp'
+ udp:
+ timeout: 15s
+ lb-7568-tcp:
+ address: ':7568/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7568-udp:
+ address: ':7568/udp'
+ udp:
+ timeout: 15s
+ lb-7569-tcp:
+ address: ':7569/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7569-udp:
+ address: ':7569/udp'
+ udp:
+ timeout: 15s
+ lb-7570-tcp:
+ address: ':7570/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7570-udp:
+ address: ':7570/udp'
+ udp:
+ timeout: 15s
+ lb-7571-tcp:
+ address: ':7571/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7571-udp:
+ address: ':7571/udp'
+ udp:
+ timeout: 15s
+ lb-7572-tcp:
+ address: ':7572/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7572-udp:
+ address: ':7572/udp'
+ udp:
+ timeout: 15s
+ lb-7573-tcp:
+ address: ':7573/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7573-udp:
+ address: ':7573/udp'
+ udp:
+ timeout: 15s
+ lb-7574-tcp:
+ address: ':7574/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7574-udp:
+ address: ':7574/udp'
+ udp:
+ timeout: 15s
+ lb-7575-tcp:
+ address: ':7575/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7575-udp:
+ address: ':7575/udp'
+ udp:
+ timeout: 15s
+ lb-7576-tcp:
+ address: ':7576/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7576-udp:
+ address: ':7576/udp'
+ udp:
+ timeout: 15s
+ lb-7577-tcp:
+ address: ':7577/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7577-udp:
+ address: ':7577/udp'
+ udp:
+ timeout: 15s
+ lb-7578-tcp:
+ address: ':7578/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7578-udp:
+ address: ':7578/udp'
+ udp:
+ timeout: 15s
+ lb-7579-tcp:
+ address: ':7579/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7579-udp:
+ address: ':7579/udp'
+ udp:
+ timeout: 15s
+ lb-7580-tcp:
+ address: ':7580/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7580-udp:
+ address: ':7580/udp'
+ udp:
+ timeout: 15s
+ lb-7581-tcp:
+ address: ':7581/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7581-udp:
+ address: ':7581/udp'
+ udp:
+ timeout: 15s
+ lb-7582-tcp:
+ address: ':7582/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7582-udp:
+ address: ':7582/udp'
+ udp:
+ timeout: 15s
+ lb-7583-tcp:
+ address: ':7583/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7583-udp:
+ address: ':7583/udp'
+ udp:
+ timeout: 15s
+ lb-7584-tcp:
+ address: ':7584/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7584-udp:
+ address: ':7584/udp'
+ udp:
+ timeout: 15s
+ lb-7585-tcp:
+ address: ':7585/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7585-udp:
+ address: ':7585/udp'
+ udp:
+ timeout: 15s
+ lb-7586-tcp:
+ address: ':7586/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7586-udp:
+ address: ':7586/udp'
+ udp:
+ timeout: 15s
+ lb-7587-tcp:
+ address: ':7587/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7587-udp:
+ address: ':7587/udp'
+ udp:
+ timeout: 15s
+ lb-7588-tcp:
+ address: ':7588/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7588-udp:
+ address: ':7588/udp'
+ udp:
+ timeout: 15s
+ lb-7589-tcp:
+ address: ':7589/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7589-udp:
+ address: ':7589/udp'
+ udp:
+ timeout: 15s
+ lb-7590-tcp:
+ address: ':7590/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7590-udp:
+ address: ':7590/udp'
+ udp:
+ timeout: 15s
+ lb-7591-tcp:
+ address: ':7591/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7591-udp:
+ address: ':7591/udp'
+ udp:
+ timeout: 15s
+ lb-7592-tcp:
+ address: ':7592/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7592-udp:
+ address: ':7592/udp'
+ udp:
+ timeout: 15s
+ lb-7593-tcp:
+ address: ':7593/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7593-udp:
+ address: ':7593/udp'
+ udp:
+ timeout: 15s
+ lb-7594-tcp:
+ address: ':7594/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7594-udp:
+ address: ':7594/udp'
+ udp:
+ timeout: 15s
+ lb-7595-tcp:
+ address: ':7595/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7595-udp:
+ address: ':7595/udp'
+ udp:
+ timeout: 15s
+ lb-7596-tcp:
+ address: ':7596/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7596-udp:
+ address: ':7596/udp'
+ udp:
+ timeout: 15s
+ lb-7597-tcp:
+ address: ':7597/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7597-udp:
+ address: ':7597/udp'
+ udp:
+ timeout: 15s
+ lb-7598-tcp:
+ address: ':7598/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7598-udp:
+ address: ':7598/udp'
+ udp:
+ timeout: 15s
+ lb-7599-tcp:
+ address: ':7599/tcp'
+ transport:
+ respondingTimeouts:
+ readTimeout: 12h
+ writeTimeout: 12h
+ idleTimeout: 30s
+ lb-7599-udp:
+ address: ':7599/udp'
+ udp:
+ timeout: 15s
+api:
+ insecure: true
+log:
+ level: INFO
+accessLog: {}
+providers:
+ providersThrottleDuration: 0.025s
+ http:
+ endpoint: >-
+ http://rivet-server:8081/traefik-provider/config/game-guard?datacenter=f288913c-735d-4188-bf9b-2fcf6eac7b9c
+ pollInterval: 0.5s
diff --git a/docker/test/rivet-server/config.yaml b/docker/test/rivet-server/config.yaml
new file mode 100644
index 0000000000..12a00abb6a
--- /dev/null
+++ b/docker/test/rivet-server/config.yaml
@@ -0,0 +1,71 @@
+server:
+ rivet:
+ auth:
+ access_kind: development
+
+ ui:
+ public_origin_regex: .*
+
+ guard:
+ # TLS not configured for local development
+ tls_enabled: false
+ # Corresponds to the ports configured in the `docker-compose.yml`
+ http_port: 7080
+ https_port: 7443
+ min_ingress_port_tcp: 7500
+ max_ingress_port_tcp: 7599
+ min_ingress_port_udp: 7500
+ max_ingress_port_udp: 7599
+
+ # Enable status checks if testing status check project
+ status:
+ token: local
+ system_test_isolate_project: default
+ system_test_isolate_environment: default
+ foundationdb:
+ connection: docker:docker@foundationdb:4500
+ cockroachdb:
+ url: postgresql://cockroachdb:26257/defaultdb?sslmode=disable
+ username: root
+ redis:
+ ephemeral:
+ url: redis://redis:6379
+ password: password
+ persistent:
+ url: redis://redis:6379
+ password: password
+ clickhouse:
+ http_url: http://clickhouse:8123
+ native_url: clickhouse://clickhouse:9000
+ username: default
+ password: default
+ provision_users:
+ vector:
+ username: vector
+ password: vector
+ role: write
+ s3:
+ region: us-east-1
+ endpoint_internal: http://seaweedfs:9000
+ endpoint_edge_internal: http://seaweedfs:9000
+ endpoint_external: http://127.0.0.1:9000
+ access_key_id: admin
+ secret_access_key: admin
+ nats:
+ urls:
+ - nats://nats:4222
+
+ # IMPORTANT:
+ # - Generate your own JWT tokens before shipping to production as seen in the
+ # self-hosting documentation.
+ # - Do not include the private key in this file. Instead, use the env var
+ # `RIVET__SERVER__JWT__PRIVATE`.
+ jwt:
+ public: |
+ -----BEGIN PUBLIC KEY-----
+ MCowBQYDK2VwAyEAx7S9ab9ErA50y0tVfFro919+BBxFSuwMKmcJ5QI853Y=
+ -----END PUBLIC KEY-----
+ private: |
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIDI+WHFytxvdtfGot36NMCI26s2Yp0+E5u9OiPf3NQX3
+ -----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/docker/test/seaweedfs/s3.json b/docker/test/seaweedfs/s3.json
new file mode 100644
index 0000000000..9b80248742
--- /dev/null
+++ b/docker/test/seaweedfs/s3.json
@@ -0,0 +1,22 @@
+{
+ "identities": [
+ {
+ "name": "admin",
+ "credentials": [
+ {
+ "accessKey": "admin",
+ "secretKey": "admin"
+ }
+ ],
+ "actions": [
+ "Admin",
+ "Read",
+ "ReadAcp",
+ "List",
+ "Tagging",
+ "Write",
+ "WriteAcp"
+ ]
+ }
+ ]
+}
diff --git a/docker/test/vector-client/vector.yaml b/docker/test/vector-client/vector.yaml
new file mode 100644
index 0000000000..278ae90592
--- /dev/null
+++ b/docker/test/vector-client/vector.yaml
@@ -0,0 +1,106 @@
+# See production config at
+# ee/packages/services/cluster/src/workflows/server/install/install_scripts/components/vector.rs
+
+api:
+ enabled: true
+
+sources:
+ prometheus_pegboard:
+ type: prometheus_scrape
+ endpoints:
+ - http://rivet-client:6090
+ scrape_interval_secs: 15
+
+ pegboard_manager:
+ type: file
+ include:
+ - /var/lib/rivet-client/log
+
+ pegboard_v8_isolate_runner:
+ type: file
+ include:
+ - /var/lib/rivet-client/runner/log
+
+ pegboard_container_runners:
+ type: file
+ include:
+ - /var/lib/rivet-client/actors/*/log
+
+transforms:
+ filter_metrics:
+ type: filter
+ inputs:
+ - prometheus_pegboard
+ condition: '!starts_with!(.name, "go_") && !starts_with!(.name, "promhttp_")'
+
+ metrics_add_meta:
+ type: remap
+ inputs:
+ - filter_metrics
+ source: |
+ .tags.server_id = "fc67e54e-5d6a-4726-ab23-77b0e54f068f"
+ .tags.datacenter_id = "f288913c-735d-4188-bf9b-2fcf6eac7b9c"
+ .tags.cluster_id = "unknown"
+ .tags.pool_type = "pegboard_isolate"
+ .tags.public_ip = "127.0.0.1"
+
+ pegboard_manager_add_meta:
+ type: remap
+ inputs:
+ - pegboard_manager
+ source: |
+ .source = "pegboard_manager"
+
+ .client_id = "fc67e54e-5d6a-4726-ab23-77b0e54f068f"
+ .server_id = "fc67e54e-5d6a-4726-ab23-77b0e54f068f"
+ .datacenter_id = "f288913c-735d-4188-bf9b-2fcf6eac7b9c"
+ .tags.cluster_id = "unknown"
+ .pool_type = "pegboard_isolate"
+ .public_ip = "127.0.0.1"
+
+ pegboard_v8_isolate_runner_add_meta:
+ type: remap
+ inputs:
+ - pegboard_v8_isolate_runner
+ source: |
+ .source = "pegboard_v8_isolate_runner"
+
+ .client_id = "fc67e54e-5d6a-4726-ab23-77b0e54f068f"
+ .server_id = "fc67e54e-5d6a-4726-ab23-77b0e54f068f"
+ .datacenter_id = "f288913c-735d-4188-bf9b-2fcf6eac7b9c"
+ .tags.cluster_id = "unknown"
+ .pool_type = "pegboard_isolate"
+ .public_ip = "127.0.0.1"
+
+ pegboard_container_runner_add_meta:
+ type: remap
+ inputs:
+ - pegboard_container_runners
+ source: |
+ .source = "pegboard_container_runner"
+ .actor_id = parse_regex!(.file, r'/etc/pegboard/actors/(?P[0-9a-fA-F-]+)/log').actor_id
+
+ .client_id = "fc67e54e-5d6a-4726-ab23-77b0e54f068f"
+ .server_id = "fc67e54e-5d6a-4726-ab23-77b0e54f068f"
+ .datacenter_id = "f288913c-735d-4188-bf9b-2fcf6eac7b9c"
+ .cluster_id = "unknown"
+ .pool_type = "pegboard_isolate"
+ .public_ip = "127.0.0.1"
+
+sinks:
+ vector_sink:
+ type: vector
+ inputs:
+ - metrics_add_meta
+ - pegboard_manager_add_meta
+ - pegboard_v8_isolate_runner_add_meta
+ - pegboard_container_runner_add_meta
+ address: vector-server:6000
+ healthcheck:
+ enabled: false
+ compression: true
+ buffer:
+ type: disk
+ max_size: 268435488
+ when_full: block
+
diff --git a/docker/test/vector-server/vector.yaml b/docker/test/vector-server/vector.yaml
new file mode 100644
index 0000000000..bfbf752d8c
--- /dev/null
+++ b/docker/test/vector-server/vector.yaml
@@ -0,0 +1,121 @@
+# See production config at ee/infra/tf/vector/vector.tf
+
+data_dir: /var/lib/vector
+
+api:
+ enabled: true
+ address: 0.0.0.0:8686
+ playground: false
+
+sources:
+ vector:
+ type: vector
+ address: 0.0.0.0:6000
+
+ tcp_json:
+ type: socket
+ mode: tcp
+ address: 0.0.0.0:6100
+ decoding:
+ codec: json
+
+ vector_metrics:
+ type: internal_metrics
+
+ vector_logs:
+ type: internal_logs
+
+transforms:
+ dynamic_servers:
+ type: filter
+ inputs:
+ - vector
+ - tcp_json
+ condition:
+ type: vrl
+ source: .source == "dynamic_servers"
+
+ job_run:
+ type: filter
+ inputs:
+ - vector
+ - tcp_json
+ condition:
+ type: vrl
+ source: .source == "job_run"
+
+ pegboard:
+ type: filter
+ inputs:
+ - vector
+ condition:
+ type: vrl
+ source: .source == "pegboard_manager" || .source == "pegboard_v8_isolate_runner"
+
+ pegboard_container_runner:
+ type: filter
+ inputs:
+ - vector
+ condition:
+ type: vrl
+ source: .source == "pegboard_container_runner"
+
+sinks:
+ prom_exporter:
+ type: prometheus_exporter
+ inputs:
+ - vector
+ - vector_metrics
+ address: 0.0.0.0:9598
+
+ console:
+ type: console
+ inputs:
+ - vector_logs
+ encoding:
+ codec: text
+
+ clickhouse_ds_logs:
+ type: clickhouse
+ inputs:
+ - dynamic_servers
+ compression: gzip
+ database: db_ds_log
+ endpoint: http://clickhouse:8123
+ table: server_logs
+ auth:
+ strategy: basic
+ user: vector
+ password: vector
+ batch:
+ timeout_secs: 1.0
+
+ clickhouse_job_run_logs:
+ type: clickhouse
+ inputs:
+ - job_run
+ compression: gzip
+ database: db_job_log
+ endpoint: http://clickhouse:8123
+ table: run_logs
+ auth:
+ strategy: basic
+ user: vector
+ password: vector
+ batch:
+ timeout_secs: 1.0
+
+ pegboard_logs:
+ type: "file"
+ inputs: ["pegboard"]
+ path: "/var/log/vector/pegboard/%Y-%m-%d.log"
+ encoding:
+ codec: "text"
+
+ pegboard_container_runner_logs:
+ type: "file"
+ inputs: ["pegboard_container_runner"]
+ path: "/var/log/vector/pegboard_container_runner/%Y-%m-%d.log"
+ encoding:
+ codec: "text"
+
diff --git a/docker/universal/Dockerfile b/docker/universal/Dockerfile
index ce54c4abf6..a0a5f61832 100644
--- a/docker/universal/Dockerfile
+++ b/docker/universal/Dockerfile
@@ -51,9 +51,9 @@ RUN \
--mount=type=cache,target=/root/.cache,id=universal-user-cache \
--mount=type=cache,target=/root/.npm,id=universal-user-npm \
--mount=type=cache,target=/root/.yarn,id=universal-user-yarn \
- RUSTFLAGS="--cfg tokio_unstable" cargo build --bin rivet-server --bin rivet-client --bin rivet-isolate-v8-runner --bin rivet-container-runner && \
+ RUSTFLAGS="--cfg tokio_unstable" cargo build --bin rivet-server --bin rivet-edge-server --bin rivet-client --bin rivet-isolate-v8-runner --bin rivet-container-runner && \
mkdir /app/dist/ && \
- cp target/debug/rivet-server target/debug/rivet-client target/debug/rivet-isolate-v8-runner target/debug/rivet-container-runner /app/dist/
+ cp target/debug/rivet-server target/debug/rivet-edge-server target/debug/rivet-client target/debug/rivet-isolate-v8-runner target/debug/rivet-container-runner /app/dist/
# MARK: Server (Full)
FROM debian:12.9-slim AS server-full
@@ -78,7 +78,8 @@ RUN apt-get update -y && \
(curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.1/migrate.linux-amd64.tar.gz | tar xvz) && \
mv migrate /usr/local/bin/migrate && \
apt-get clean && \
- rm -rf /var/lib/apt/lists/*
+ rm -rf /var/lib/apt/lists/* && \
+ curl -Lf -o /lib/libfdb_c.so "https://github.com/apple/foundationdb/releases/download/7.1.60/libfdb_c.x86_64.so"
COPY --from=builder /app/dist/rivet-server /usr/bin/rivet-server
@@ -91,12 +92,43 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y && \
apt-get install -y ca-certificates openssl && \
apt-get clean && \
- rm -rf /var/lib/apt/lists/*
+ rm -rf /var/lib/apt/lists/* && \
+ curl -Lf -o /lib/libfdb_c.so "https://github.com/apple/foundationdb/releases/download/7.1.60/libfdb_c.x86_64.so"
COPY --from=builder /app/dist/rivet-server /usr/bin/rivet-server
CMD ["/usr/bin/rivet-server"]
+# MARK: Edge server
+FROM debian:12.1-slim AS edge-server
+
+ENV DEBIAN_FRONTEND=noninteractive
+# - Install curl for health checks
+# - Install go-migrate for running migrations
+# - Install database clients to be able to run `rivet db shell ...` (Redis, Postgres, ClickHouse)
+RUN apt-get update -y && \
+ apt-get install -y \
+ ca-certificates \
+ openssl \
+ curl \
+ redis-tools \
+ postgresql-client \
+ gpg \
+ dirmngr && \
+ curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg && \
+ echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb stable main" | tee /etc/apt/sources.list.d/clickhouse.list && \
+ apt-get update -y && \
+ apt-get install -y clickhouse-client && \
+ (curl -L https://github.com/golang-migrate/migrate/releases/download/v4.18.1/migrate.linux-amd64.tar.gz | tar xvz) && \
+ mv migrate /usr/local/bin/migrate && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/* && \
+ curl -Lf -o /lib/libfdb_c.so "https://github.com/apple/foundationdb/releases/download/7.1.60/libfdb_c.x86_64.so"
+
+COPY --from=builder /app/dist/rivet-edge-server /usr/bin/rivet-edge-server
+
+CMD ["/usr/bin/rivet-edge-server"]
+
# MARK: Runner base
FROM --platform=linux/amd64 debian:12.9-slim AS base-runner
ENV DEBIAN_FRONTEND=noninteractive
diff --git a/frontend/apps/hub/vite.config.ts.timestamp-1738365317822-49270a449d6b9.mjs b/frontend/apps/hub/vite.config.ts.timestamp-1738365317822-49270a449d6b9.mjs
new file mode 100644
index 0000000000..053ff055aa
--- /dev/null
+++ b/frontend/apps/hub/vite.config.ts.timestamp-1738365317822-49270a449d6b9.mjs
@@ -0,0 +1,108 @@
+// vite.config.ts
+import * as crypto from "node:crypto";
+import path from "node:path";
+import { sentryVitePlugin } from "file:///home/rivet/rivet-ee/oss/node_modules/@sentry/vite-plugin/dist/esm/index.mjs";
+import { transformerNotationFocus } from "file:///home/rivet/rivet-ee/oss/node_modules/@shikijs/transformers/dist/index.mjs";
+import { TanStackRouterVite } from "file:///home/rivet/rivet-ee/oss/node_modules/@tanstack/router-vite-plugin/dist/esm/index.js";
+import react from "file:///home/rivet/rivet-ee/oss/node_modules/@vitejs/plugin-react/dist/index.mjs";
+import * as shiki from "file:///home/rivet/rivet-ee/oss/node_modules/shiki/dist/index.mjs";
+import { defineConfig } from "file:///home/rivet/rivet-ee/oss/node_modules/vite/dist/node/index.js";
+import vitePluginFaviconsInject from "file:///home/rivet/rivet-ee/oss/node_modules/vite-plugin-favicons-inject/dist/cjs/index.js";
+var __vite_injected_original_dirname = "/home/rivet/rivet-ee/oss/frontend/apps/hub";
+var GIT_BRANCH = process.env.CF_PAGES_BRANCH;
+var GIT_SHA = process.env.CF_PAGES_COMMIT_SHA;
+var vite_config_default = defineConfig({
+ base: "./",
+ plugins: [
+ react(),
+ TanStackRouterVite(),
+ vitePluginFaviconsInject(
+ path.resolve(__vite_injected_original_dirname, "public", "icon-white.svg"),
+ {
+ appName: "Rivet Hub",
+ theme_color: "#ff4f00"
+ }
+ ),
+ shikiTransformer(),
+ process.env.SENTRY_AUTH_TOKEN ? sentryVitePlugin({
+ org: "rivet-gaming",
+ project: "hub",
+ authToken: process.env.SENTRY_AUTH_TOKEN,
+ release: GIT_BRANCH === "main" ? { name: GIT_SHA } : void 0
+ }) : null
+ ],
+ server: {
+ port: 5080
+ },
+ define: {
+ // Provide a unique build ID for cache busting
+ __APP_BUILD_ID__: JSON.stringify(
+ `${(/* @__PURE__ */ new Date()).toISOString()}@${crypto.randomUUID()}`
+ )
+ },
+ resolve: {
+ alias: {
+ "@": path.resolve(__vite_injected_original_dirname, "./src")
+ }
+ },
+ build: {
+ sourcemap: true,
+ commonjsOptions: {
+ include: [/@rivet-gg\/components/, /node_modules/]
+ }
+ },
+ worker: {
+ format: "es"
+ }
+});
+async function shikiTransformer() {
+ const cssVariableTheme = shiki.createCssVariablesTheme({
+ name: "css-variables",
+ variablePrefix: "--shiki-",
+ variableDefaults: {},
+ fontStyle: true
+ });
+ let highlighter;
+ return {
+ name: "shiki",
+ async transform(code, id) {
+ if (id.includes("?shiki")) {
+ highlighter ??= await shiki.getSingletonHighlighter({
+ themes: [cssVariableTheme],
+ langs: [
+ "bash",
+ "batch",
+ "cpp",
+ "csharp",
+ "docker",
+ "gdscript",
+ "html",
+ "ini",
+ "js",
+ "json",
+ "json",
+ "powershell",
+ "ts",
+ "typescript",
+ "yaml",
+ "http",
+ "prisma"
+ ]
+ });
+ const params = new URLSearchParams(id.split("?")[1]);
+ const output = highlighter.codeToHtml(code, {
+ lang: params.get("lang") ?? "bash",
+ theme: "css-variables",
+ transformers: [transformerNotationFocus()]
+ });
+ return `export default ${JSON.stringify(
+ output
+ )};export const source = ${JSON.stringify(code)}`;
+ }
+ }
+ };
+}
+export {
+ vite_config_default as default
+};
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvaG9tZS9yaXZldC9yaXZldC1lZS9vc3MvZnJvbnRlbmQvYXBwcy9odWJcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9ob21lL3JpdmV0L3JpdmV0LWVlL29zcy9mcm9udGVuZC9hcHBzL2h1Yi92aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vaG9tZS9yaXZldC9yaXZldC1lZS9vc3MvZnJvbnRlbmQvYXBwcy9odWIvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgKiBhcyBjcnlwdG8gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBzZW50cnlWaXRlUGx1Z2luIH0gZnJvbSBcIkBzZW50cnkvdml0ZS1wbHVnaW5cIjtcbmltcG9ydCB7IHRyYW5zZm9ybWVyTm90YXRpb25Gb2N1cyB9IGZyb20gXCJAc2hpa2lqcy90cmFuc2Zvcm1lcnNcIjtcbmltcG9ydCB7IFRhblN0YWNrUm91dGVyVml0ZSB9IGZyb20gXCJAdGFuc3RhY2svcm91dGVyLXZpdGUtcGx1Z2luXCI7XG5pbXBvcnQgcmVhY3QgZnJvbSBcIkB2aXRlanMvcGx1Z2luLXJlYWN0XCI7XG5pbXBvcnQgKiBhcyBzaGlraSBmcm9tIFwic2hpa2lcIjtcbmltcG9ydCB7IHR5cGUgUGx1Z2luLCBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHZpdGVQbHVnaW5GYXZpY29uc0luamVjdCBmcm9tIFwidml0ZS1wbHVnaW4tZmF2aWNvbnMtaW5qZWN0XCI7XG5cbi8vIFRoZXNlIGFyZSBvbmx5IG5lZWRlZCBpbiBDSS4gVGhleSdsbCBiZSB1bmRlZmluZWQgaW4gZGV2LlxuY29uc3QgR0lUX0JSQU5DSCA9IHByb2Nlc3MuZW52LkNGX1BBR0VTX0JSQU5DSDtcbmNvbnN0IEdJVF9TSEEgPSBwcm9jZXNzLmVudi5DRl9QQUdFU19DT01NSVRfU0hBO1xuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcblx0YmFzZTogXCIuL1wiLFxuXHRwbHVnaW5zOiBbXG5cdFx0cmVhY3QoKSxcblx0XHRUYW5TdGFja1JvdXRlclZpdGUoKSxcblx0XHR2aXRlUGx1Z2luRmF2aWNvbnNJbmplY3QoXG5cdFx0XHRwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcInB1YmxpY1wiLCBcImljb24td2hpdGUuc3ZnXCIpLFxuXHRcdFx0e1xuXHRcdFx0XHRhcHBOYW1lOiBcIlJpdmV0IEh1YlwiLFxuXHRcdFx0XHR0aGVtZV9jb2xvcjogXCIjZmY0ZjAwXCIsXG5cdFx0XHR9LFxuXHRcdCksXG5cdFx0c2hpa2lUcmFuc2Zvcm1lcigpLFxuXHRcdHByb2Nlc3MuZW52LlNFTlRSWV9BVVRIX1RPS0VOXG5cdFx0XHQ/IHNlbnRyeVZpdGVQbHVnaW4oe1xuXHRcdFx0XHRcdG9yZzogXCJyaXZldC1nYW1pbmdcIixcblx0XHRcdFx0XHRwcm9qZWN0OiBcImh1YlwiLFxuXHRcdFx0XHRcdGF1dGhUb2tlbjogcHJvY2Vzcy5lbnYuU0VOVFJZX0FVVEhfVE9LRU4sXG5cdFx0XHRcdFx0cmVsZWFzZTpcblx0XHRcdFx0XHRcdEdJVF9CUkFOQ0ggPT09IFwibWFpblwiID8geyBuYW1lOiBHSVRfU0hBIH0gOiB1bmRlZmluZWQsXG5cdFx0XHRcdH0pXG5cdFx0XHQ6IG51bGwsXG5cdF0sXG5cdHNlcnZlcjoge1xuXHRcdHBvcnQ6IDUwODAsXG5cdH0sXG5cdGRlZmluZToge1xuXHRcdC8vIFByb3ZpZGUgYSB1bmlxdWUgYnVpbGQgSUQgZm9yIGNhY2hlIGJ1c3Rpbmdcblx0XHRfX0FQUF9CVUlMRF9JRF9fOiBKU09OLnN0cmluZ2lmeShcblx0XHRcdGAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1AJHtjcnlwdG8ucmFuZG9tVVVJRCgpfWAsXG5cdFx0KSxcblx0fSxcblx0cmVzb2x2ZToge1xuXHRcdGFsaWFzOiB7XG5cdFx0XHRcIkBcIjogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCIuL3NyY1wiKSxcblx0XHR9LFxuXHR9LFxuXHRidWlsZDoge1xuXHRcdHNvdXJjZW1hcDogdHJ1ZSxcblx0XHRjb21tb25qc09wdGlvbnM6IHtcblx0XHRcdGluY2x1ZGU6IFsvQHJpdmV0LWdnXFwvY29tcG9uZW50cy8sIC9ub2RlX21vZHVsZXMvXSxcblx0XHR9LFxuXHR9LFxuXHR3b3JrZXI6IHtcblx0XHRmb3JtYXQ6IFwiZXNcIixcblx0fSxcbn0pO1xuXG5hc3luYyBmdW5jdGlvbiBzaGlraVRyYW5zZm9ybWVyKCk6IFByb21pc2U8UGx1Z2luPiB7XG5cdGNvbnN0IGNzc1ZhcmlhYmxlVGhlbWUgPSBzaGlraS5jcmVhdGVDc3NWYXJpYWJsZXNUaGVtZSh7XG5cdFx0bmFtZTogXCJjc3MtdmFyaWFibGVzXCIsXG5cdFx0dmFyaWFibGVQcmVmaXg6IFwiLS1zaGlraS1cIixcblx0XHR2YXJpYWJsZURlZmF1bHRzOiB7fSxcblx0XHRmb250U3R5bGU6IHRydWUsXG5cdH0pO1xuXG5cdGxldCBoaWdobGlnaHRlcjogc2hpa2kuSGlnaGxpZ2h0ZXIgfCB1bmRlZmluZWQ7XG5cblx0cmV0dXJuIHtcblx0XHRuYW1lOiBcInNoaWtpXCIsXG5cdFx0YXN5bmMgdHJhbnNmb3JtKGNvZGUsIGlkKSB7XG5cdFx0XHRpZiAoaWQuaW5jbHVkZXMoXCI/c2hpa2lcIikpIHtcblx0XHRcdFx0aGlnaGxpZ2h0ZXIgPz89IGF3YWl0IHNoaWtpLmdldFNpbmdsZXRvbkhpZ2hsaWdodGVyKHtcblx0XHRcdFx0XHR0aGVtZXM6IFtjc3NWYXJpYWJsZVRoZW1lXSxcblx0XHRcdFx0XHRsYW5nczogW1xuXHRcdFx0XHRcdFx0XCJiYXNoXCIsXG5cdFx0XHRcdFx0XHRcImJhdGNoXCIsXG5cdFx0XHRcdFx0XHRcImNwcFwiLFxuXHRcdFx0XHRcdFx0XCJjc2hhcnBcIixcblx0XHRcdFx0XHRcdFwiZG9ja2VyXCIsXG5cdFx0XHRcdFx0XHRcImdkc2NyaXB0XCIsXG5cdFx0XHRcdFx0XHRcImh0bWxcIixcblx0XHRcdFx0XHRcdFwiaW5pXCIsXG5cdFx0XHRcdFx0XHRcImpzXCIsXG5cdFx0XHRcdFx0XHRcImpzb25cIixcblx0XHRcdFx0XHRcdFwianNvblwiLFxuXHRcdFx0XHRcdFx0XCJwb3dlcnNoZWxsXCIsXG5cdFx0XHRcdFx0XHRcInRzXCIsXG5cdFx0XHRcdFx0XHRcInR5cGVzY3JpcHRcIixcblx0XHRcdFx0XHRcdFwieWFtbFwiLFxuXHRcdFx0XHRcdFx0XCJodHRwXCIsXG5cdFx0XHRcdFx0XHRcInByaXNtYVwiLFxuXHRcdFx0XHRcdF0sXG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRcdGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoaWQuc3BsaXQoXCI/XCIpWzFdKTtcblx0XHRcdFx0Y29uc3Qgb3V0cHV0ID0gaGlnaGxpZ2h0ZXIuY29kZVRvSHRtbChjb2RlLCB7XG5cdFx0XHRcdFx0bGFuZzogcGFyYW1zLmdldChcImxhbmdcIikgPz8gXCJiYXNoXCIsXG5cdFx0XHRcdFx0dGhlbWU6IFwiY3NzLXZhcmlhYmxlc1wiLFxuXHRcdFx0XHRcdHRyYW5zZm9ybWVyczogW3RyYW5zZm9ybWVyTm90YXRpb25Gb2N1cygpXSxcblx0XHRcdFx0fSk7XG5cdFx0XHRcdHJldHVybiBgZXhwb3J0IGRlZmF1bHQgJHtKU09OLnN0cmluZ2lmeShcblx0XHRcdFx0XHRvdXRwdXQsXG5cdFx0XHRcdCl9O2V4cG9ydCBjb25zdCBzb3VyY2UgPSAke0pTT04uc3RyaW5naWZ5KGNvZGUpfWA7XG5cdFx0XHR9XG5cdFx0fSxcblx0fTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBZ1QsWUFBWSxZQUFZO0FBQ3hVLE9BQU8sVUFBVTtBQUNqQixTQUFTLHdCQUF3QjtBQUNqQyxTQUFTLGdDQUFnQztBQUN6QyxTQUFTLDBCQUEwQjtBQUNuQyxPQUFPLFdBQVc7QUFDbEIsWUFBWSxXQUFXO0FBQ3ZCLFNBQXNCLG9CQUFvQjtBQUMxQyxPQUFPLDhCQUE4QjtBQVJyQyxJQUFNLG1DQUFtQztBQVd6QyxJQUFNLGFBQWEsUUFBUSxJQUFJO0FBQy9CLElBQU0sVUFBVSxRQUFRLElBQUk7QUFHNUIsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDM0IsTUFBTTtBQUFBLEVBQ04sU0FBUztBQUFBLElBQ1IsTUFBTTtBQUFBLElBQ04sbUJBQW1CO0FBQUEsSUFDbkI7QUFBQSxNQUNDLEtBQUssUUFBUSxrQ0FBVyxVQUFVLGdCQUFnQjtBQUFBLE1BQ2xEO0FBQUEsUUFDQyxTQUFTO0FBQUEsUUFDVCxhQUFhO0FBQUEsTUFDZDtBQUFBLElBQ0Q7QUFBQSxJQUNBLGlCQUFpQjtBQUFBLElBQ2pCLFFBQVEsSUFBSSxvQkFDVCxpQkFBaUI7QUFBQSxNQUNqQixLQUFLO0FBQUEsTUFDTCxTQUFTO0FBQUEsTUFDVCxXQUFXLFFBQVEsSUFBSTtBQUFBLE1BQ3ZCLFNBQ0MsZUFBZSxTQUFTLEVBQUUsTUFBTSxRQUFRLElBQUk7QUFBQSxJQUM5QyxDQUFDLElBQ0E7QUFBQSxFQUNKO0FBQUEsRUFDQSxRQUFRO0FBQUEsSUFDUCxNQUFNO0FBQUEsRUFDUDtBQUFBLEVBQ0EsUUFBUTtBQUFBO0FBQUEsSUFFUCxrQkFBa0IsS0FBSztBQUFBLE1BQ3RCLElBQUcsb0JBQUksS0FBSyxHQUFFLFlBQVksQ0FBQyxJQUFXLGtCQUFXLENBQUM7QUFBQSxJQUNuRDtBQUFBLEVBQ0Q7QUFBQSxFQUNBLFNBQVM7QUFBQSxJQUNSLE9BQU87QUFBQSxNQUNOLEtBQUssS0FBSyxRQUFRLGtDQUFXLE9BQU87QUFBQSxJQUNyQztBQUFBLEVBQ0Q7QUFBQSxFQUNBLE9BQU87QUFBQSxJQUNOLFdBQVc7QUFBQSxJQUNYLGlCQUFpQjtBQUFBLE1BQ2hCLFNBQVMsQ0FBQyx5QkFBeUIsY0FBYztBQUFBLElBQ2xEO0FBQUEsRUFDRDtBQUFBLEVBQ0EsUUFBUTtBQUFBLElBQ1AsUUFBUTtBQUFBLEVBQ1Q7QUFDRCxDQUFDO0FBRUQsZUFBZSxtQkFBb0M7QUFDbEQsUUFBTSxtQkFBeUIsOEJBQXdCO0FBQUEsSUFDdEQsTUFBTTtBQUFBLElBQ04sZ0JBQWdCO0FBQUEsSUFDaEIsa0JBQWtCLENBQUM7QUFBQSxJQUNuQixXQUFXO0FBQUEsRUFDWixDQUFDO0FBRUQsTUFBSTtBQUVKLFNBQU87QUFBQSxJQUNOLE1BQU07QUFBQSxJQUNOLE1BQU0sVUFBVSxNQUFNLElBQUk7QUFDekIsVUFBSSxHQUFHLFNBQVMsUUFBUSxHQUFHO0FBQzFCLHdCQUFnQixNQUFZLDhCQUF3QjtBQUFBLFVBQ25ELFFBQVEsQ0FBQyxnQkFBZ0I7QUFBQSxVQUN6QixPQUFPO0FBQUEsWUFDTjtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxVQUNEO0FBQUEsUUFDRCxDQUFDO0FBRUQsY0FBTSxTQUFTLElBQUksZ0JBQWdCLEdBQUcsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0FBQ25ELGNBQU0sU0FBUyxZQUFZLFdBQVcsTUFBTTtBQUFBLFVBQzNDLE1BQU0sT0FBTyxJQUFJLE1BQU0sS0FBSztBQUFBLFVBQzVCLE9BQU87QUFBQSxVQUNQLGNBQWMsQ0FBQyx5QkFBeUIsQ0FBQztBQUFBLFFBQzFDLENBQUM7QUFDRCxlQUFPLGtCQUFrQixLQUFLO0FBQUEsVUFDN0I7QUFBQSxRQUNELENBQUMsMEJBQTBCLEtBQUssVUFBVSxJQUFJLENBQUM7QUFBQSxNQUNoRDtBQUFBLElBQ0Q7QUFBQSxFQUNEO0FBQ0Q7IiwKICAibmFtZXMiOiBbXQp9Cg==
diff --git a/frontend/packages/components/package.json b/frontend/packages/components/package.json
index aa1dbc6eb2..19d0730947 100644
--- a/frontend/packages/components/package.json
+++ b/frontend/packages/components/package.json
@@ -3,7 +3,11 @@
"private": true,
"version": "1.0.0",
"type": "module",
- "files": ["dist", "src", "public"],
+ "files": [
+ "dist",
+ "src",
+ "public"
+ ],
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"sideEffects": false,
diff --git a/frontend/packages/icons/package.json b/frontend/packages/icons/package.json
index f5f2f849a7..a38c7a569f 100644
--- a/frontend/packages/icons/package.json
+++ b/frontend/packages/icons/package.json
@@ -2,7 +2,12 @@
"name": "@rivet-gg/icons",
"version": "1.0.0",
"sideEffects": false,
- "files": ["scripts", "manifest.json", "src", "dist"],
+ "files": [
+ "scripts",
+ "manifest.json",
+ "src",
+ "dist"
+ ],
"scripts": {
"postinstall": "node scripts/postinstall.js"
},
diff --git a/packages/api/actor/Cargo.toml b/packages/api/actor/Cargo.toml
deleted file mode 100644
index 3a18e44134..0000000000
--- a/packages/api/actor/Cargo.toml
+++ /dev/null
@@ -1,73 +0,0 @@
-[package]
-name = "api-actor"
-version.workspace = true
-authors.workspace = true
-license.workspace = true
-edition.workspace = true
-
-[dependencies]
-api-helper.workspace = true
-chirp-client.workspace = true
-rivet-operation.workspace = true
-chrono = "0.4"
-http = "0.2"
-hyper = { version = "0.14", features = ["server", "http1", "stream", "tcp"] }
-lazy_static = "1.4"
-rivet-api.workspace = true
-rivet-cache.workspace = true
-rivet-claims.workspace = true
-rivet-health-checks.workspace = true
-rivet-convert.workspace = true
-rivet-pools.workspace = true
-s3-util.workspace = true
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-base64 = "0.13"
-tokio = { version = "1.40" }
-tracing = "0.1"
-tracing-futures = "0.2"
-tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "json", "ansi"] }
-url = "2.2.2"
-util-team.workspace = true
-uuid = { version = "1", features = ["v4"] }
-
-build-create.workspace = true
-build-get.workspace = true
-build-list-for-env.workspace = true
-build.workspace = true
-cluster.workspace = true
-ds-log-export.workspace = true
-ds-log-read.workspace = true
-ds.workspace = true
-game-get.workspace = true
-game-namespace-get.workspace = true
-game-namespace-resolve-name-id.workspace = true
-game-resolve-name-id.workspace = true
-game-version-get.workspace = true
-pegboard.workspace = true
-region-recommend.workspace = true
-rivet-config.workspace = true
-rivet-env.workspace = true
-team-get.workspace = true
-token-create.workspace = true
-token-revoke.workspace = true
-upload-complete.workspace = true
-upload-get.workspace = true
-user-get.workspace = true
-user-identity-get.workspace = true
-user-team-list.workspace = true
-
-[dev-dependencies]
-rivet-connection.workspace = true
-reqwest = "0.11"
-
-cdn-namespace-domain-create.workspace = true
-cloud-namespace-token-development-create.workspace = true
-cloud-namespace-token-public-create.workspace = true
-faker-build.workspace = true
-faker-game-namespace.workspace = true
-faker-game-version.workspace = true
-faker-game.workspace = true
-faker-region.workspace = true
-game-get.workspace = true
-region-get.workspace = true
diff --git a/packages/api/actor/src/route/actors.rs b/packages/api/actor/src/route/actors.rs
deleted file mode 100644
index e3462230b9..0000000000
--- a/packages/api/actor/src/route/actors.rs
+++ /dev/null
@@ -1,1054 +0,0 @@
-use std::collections::{HashMap, HashSet};
-
-use api_helper::{anchor::WatchIndexQuery, ctx::Ctx};
-use futures_util::{StreamExt, TryStreamExt};
-use proto::backend;
-use rivet_api::models;
-use rivet_convert::{ApiInto, ApiTryInto};
-use rivet_operation::prelude::*;
-use serde::Deserialize;
-use serde_json::json;
-
-use crate::{
- assert,
- auth::{Auth, CheckOpts, CheckOutput},
- utils::build_global_query_compat,
-};
-
-use super::GlobalQuery;
-
-#[derive(Debug, Clone, Deserialize)]
-pub struct GlobalEndpointTypeQuery {
- #[serde(flatten)]
- global: GlobalQuery,
- endpoint_type: Option,
-}
-
-// MARK: GET /actors/{}
-pub async fn get(
- ctx: Ctx,
- actor_id: Uuid,
- watch_index: WatchIndexQuery,
- query: GlobalEndpointTypeQuery,
-) -> GlobalResult {
- get_inner(&ctx, actor_id, watch_index, query).await
-}
-
-async fn get_inner(
- ctx: &Ctx,
- actor_id: Uuid,
- _watch_index: WatchIndexQuery,
- query: GlobalEndpointTypeQuery,
-) -> GlobalResult {
- let CheckOutput { env_id, .. } = ctx
- .auth()
- .check(
- ctx.op_ctx(),
- CheckOpts {
- query: &query.global,
- allow_service_token: true,
- opt_auth: false,
- },
- )
- .await?;
-
- // Get the server
- let servers_res = ctx
- .op(ds::ops::server::get::Input {
- server_ids: vec![actor_id],
- endpoint_type: query.endpoint_type.map(ApiInto::api_into),
- })
- .await?;
- let server = unwrap_with!(servers_res.servers.first(), ACTOR_NOT_FOUND);
-
- // Get the datacenter
- let dc_res = ctx
- .op(cluster::ops::datacenter::get::Input {
- datacenter_ids: vec![server.datacenter_id],
- })
- .await?;
- let dc = unwrap!(dc_res.datacenters.first());
-
- // Validate token can access server
- ensure_with!(server.env_id == env_id, ACTOR_NOT_FOUND);
-
- Ok(models::ActorGetActorResponse {
- actor: Box::new(ds::types::convert_actor_to_api(server.clone(), dc)?),
- })
-}
-
-pub async fn get_deprecated(
- ctx: Ctx,
- game_id: Uuid,
- env_id: Uuid,
- actor_id: Uuid,
- watch_index: WatchIndexQuery,
-) -> GlobalResult {
- let global = build_global_query_compat(&ctx, game_id, env_id).await?;
- let get_res = get_inner(
- &ctx,
- actor_id,
- watch_index,
- GlobalEndpointTypeQuery {
- global,
- endpoint_type: None,
- },
- )
- .await?;
-
- let game_res = ctx
- .op(cluster::ops::get_for_game::Input {
- game_ids: vec![game_id],
- })
- .await?;
- let game = unwrap!(game_res.games.first());
-
- let dc_resolve_res = ctx
- .op(cluster::ops::datacenter::resolve_for_name_id::Input {
- cluster_id: game.cluster_id,
- name_ids: vec![get_res.actor.region.clone()],
- })
- .await?;
- let dc_id = unwrap!(dc_resolve_res.datacenters.first()).datacenter_id;
-
- let dc_res = ctx
- .op(cluster::ops::datacenter::get::Input {
- datacenter_ids: vec![dc_id],
- })
- .await?;
- let dc = unwrap!(dc_res.datacenters.first());
-
- Ok(models::ServersGetServerResponse {
- server: Box::new(legacy_convert_actor_to_server(*get_res.actor, dc)?),
- })
-}
-
-// MARK: POST /actors
-pub async fn create(
- ctx: Ctx,
- body: models::ActorCreateActorRequest,
- query: GlobalEndpointTypeQuery,
-) -> GlobalResult {
- let CheckOutput { game_id, env_id } = ctx
- .auth()
- .check(
- ctx.op_ctx(),
- CheckOpts {
- query: &query.global,
- allow_service_token: true,
- opt_auth: false,
- },
- )
- .await?;
-
- let (clusters_res, game_configs_res, build) = tokio::try_join!(
- ctx.op(cluster::ops::get_for_game::Input {
- game_ids: vec![game_id],
- }),
- ctx.op(ds::ops::game_config::get::Input {
- game_ids: vec![game_id],
- }),
- resolve_build(&ctx, game_id, env_id, body.build, body.build_tags.flatten()),
- )?;
- let cluster_id = unwrap!(clusters_res.games.first()).cluster_id;
- let game_config = unwrap!(game_configs_res.game_configs.first());
-
- let datacenter_id = resolve_dc_id(&ctx, cluster_id, body.region.clone()).await?;
-
- let tags = unwrap_with!(
- serde_json::from_value(body.tags.unwrap_or_default()).ok(),
- API_BAD_BODY,
- error = "`tags` must be `Map`"
- );
-
- let resources = match build.kind {
- build::types::BuildKind::DockerImage | build::types::BuildKind::OciBundle => {
- let resources = unwrap_with!(
- body.resources,
- API_BAD_BODY,
- error = "`resources` must be set for actors using Docker builds"
- );
-
- (*resources).api_into()
- }
- build::types::BuildKind::JavaScript => {
- ensure_with!(
- body.resources.is_none(),
- API_BAD_BODY,
- error = "actors using JavaScript builds cannot set `resources`"
- );
-
- ds::types::ServerResources::default_isolate()
- }
- };
-
- tracing::info!(?tags, "creating server with tags");
-
- let server_id = Uuid::new_v4();
-
- let mut ready_sub = ctx
- .subscribe::(("server_id", server_id))
- .await?;
- let mut fail_sub = ctx
- .subscribe::(("server_id", server_id))
- .await?;
- let mut destroy_sub = ctx
- .subscribe::(("server_id", server_id))
- .await?;
-
- let network = body.network.unwrap_or_default();
-
- ctx.workflow(ds::workflows::server::Input {
- server_id,
- env_id,
- datacenter_id,
- cluster_id,
- runtime: game_config.runtime,
- tags,
- resources,
- lifecycle: body.lifecycle.map(|x| (*x).api_into()).unwrap_or_else(|| {
- ds::types::ServerLifecycle {
- kill_timeout_ms: 0,
- durable: false,
- }
- }),
- image_id: build.build_id,
- root_user_enabled: game_config.root_user_enabled,
- // args: body.runtime.arguments.unwrap_or_default(),
- args: Vec::new(),
- network_mode: network.mode.unwrap_or_default().api_into(),
- environment: body.runtime.and_then(|r| r.environment).unwrap_or_default(),
- network_ports: unwrap!(network
- .ports
- .unwrap_or_default()
- .into_iter()
- .map(|(s, p)| GlobalResult::Ok((
- s.clone(),
- ds::workflows::server::Port {
- internal_port: p.internal_port.map(TryInto::try_into).transpose()?,
- routing: if let Some(routing) = p.routing {
- match *routing {
- models::ActorPortRouting {
- guard: Some(_gg),
- host: None,
- } => ds::types::Routing::GameGuard {
- protocol: p.protocol.api_into(),
- // Temporarily disabled
- // authorization: match gg.authorization.as_deref() {
- // Some(models::ActorPortAuthorization {
- // bearer: Some(token),
- // ..
- // }) => ds::types::PortAuthorization::Bearer(token.clone()),
- // Some(models::ActorPortAuthorization {
- // query: Some(query),
- // ..
- // }) => ds::types::PortAuthorization::Query(
- // query.key.clone(),
- // query.value.clone(),
- // ),
- // _ => ds::types::PortAuthorization::None,
- // },
- authorization: ds::types::PortAuthorization::None,
- },
- models::ActorPortRouting {
- guard: None,
- host: Some(_),
- } => ds::types::Routing::Host {
- protocol: match p.protocol.api_try_into() {
- Err(err) if GlobalError::is(&err, formatted_error::code::ACTOR_FAILED_TO_CREATE) => {
- // Add location
- bail_with!(
- ACTOR_FAILED_TO_CREATE,
- error = format!("network.ports[{s:?}].protocol: Host port protocol must be either TCP or UDP.")
- );
- }
- x => x?,
- },
- },
- models::ActorPortRouting { .. } => {
- bail_with!(
- ACTOR_FAILED_TO_CREATE,
- error = format!("network.ports[{s:?}].routing: Must specify either `guard` or `host` routing type.")
- );
- }
- }
- } else {
- ds::types::Routing::GameGuard {
- protocol: p.protocol.api_into(),
- authorization: ds::types::PortAuthorization::None,
- }
- }
- }
- )))
- .collect::>>()),
- })
- .tag("server_id", server_id)
- .dispatch()
- .await?;
-
- // Wait for ready, fail, or destroy
- tokio::select! {
- res = ready_sub.next() => { res?; },
- res = fail_sub.next() => {
- let msg = res?;
- bail_with!(ACTOR_FAILED_TO_CREATE, error = msg.message);
- }
- res = destroy_sub.next() => {
- res?;
- bail_with!(ACTOR_FAILED_TO_CREATE, error = "Actor failed before reaching a ready state.");
- }
- }
-
- let servers_res = ctx
- .op(ds::ops::server::get::Input {
- server_ids: vec![server_id],
- endpoint_type: query.endpoint_type.map(ApiInto::api_into),
- })
- .await?;
- let server = unwrap_with!(servers_res.servers.first(), ACTOR_NOT_FOUND);
-
- let dc_res = ctx
- .op(cluster::ops::datacenter::get::Input {
- datacenter_ids: vec![server.datacenter_id],
- })
- .await?;
- let dc = unwrap!(dc_res.datacenters.first());
-
- Ok(models::ActorCreateActorResponse {
- actor: Box::new(ds::types::convert_actor_to_api(server.clone(), dc)?),
- })
-}
-
-pub async fn create_deprecated(
- ctx: Ctx,
- game_id: Uuid,
- env_id: Uuid,
- body: models::ServersCreateServerRequest,
-) -> GlobalResult {
- // Resolve region slug
- let dc_res = ctx
- .op(cluster::ops::datacenter::get::Input {
- datacenter_ids: vec![body.datacenter],
- })
- .await?;
- let dc = unwrap!(dc_res.datacenters.first());
-
- let global = build_global_query_compat(&ctx, game_id, env_id).await?;
- let create_res = create(
- ctx,
- models::ActorCreateActorRequest {
- region: Some(dc.name_id.clone()),
- lifecycle: body.lifecycle.map(|l| {
- Box::new(models::ActorLifecycle {
- kill_timeout: l.kill_timeout,
- durable: Some(false),
- })
- }),
- network: Some(Box::new(models::ActorCreateActorNetworkRequest {
- mode: body.network.mode.map(|n| match n {
- models::ServersNetworkMode::Host => models::ActorNetworkMode::Host,
- models::ServersNetworkMode::Bridge => models::ActorNetworkMode::Bridge,
- }),
- ports: Some(
- body.network
- .ports
- .into_iter()
- .map(|(k, p)| {
- (
- k,
- models::ActorCreateActorPortRequest {
- internal_port: p.internal_port,
- protocol: match p.protocol {
- models::ServersPortProtocol::Http => {
- models::ActorPortProtocol::Http
- }
- models::ServersPortProtocol::Https => {
- models::ActorPortProtocol::Https
- }
- models::ServersPortProtocol::Tcp => {
- models::ActorPortProtocol::Tcp
- }
- models::ServersPortProtocol::TcpTls => {
- models::ActorPortProtocol::TcpTls
- }
- models::ServersPortProtocol::Udp => {
- models::ActorPortProtocol::Udp
- }
- },
- routing: p.routing.map(|r| {
- Box::new(models::ActorPortRouting {
- // Temporarily disabled
- // guard: r.game_guard.map(|_| {
- // Box::new(models::ActorGuardRouting::default())
- // }),
- guard: r.game_guard.map(|_| json!({})),
- host: r.host.map(|_| json!({})),
- })
- }),
- },
- )
- })
- .collect(),
- ),
- })),
- resources: Some(Box::new(models::ActorResources {
- cpu: body.resources.cpu,
- memory: body.resources.memory,
- })),
- runtime: Some(Box::new(models::ActorCreateActorRuntimeRequest {
- environment: body.runtime.environment,
- })),
- build: Some(body.runtime.build),
- build_tags: None,
- tags: body.tags,
- },
- GlobalEndpointTypeQuery {
- global,
- endpoint_type: None,
- },
- )
- .await?;
-
- Ok(models::ServersCreateServerResponse {
- server: Box::new(legacy_convert_actor_to_server(*create_res.actor, &dc)?),
- })
-}
-
-// MARK: DELETE /actors/{}
-#[derive(Debug, Clone, Deserialize)]
-pub struct DeleteQuery {
- #[serde(flatten)]
- global: GlobalQuery,
- override_kill_timeout: Option,
-}
-
-pub async fn destroy(
- ctx: Ctx,
- actor_id: Uuid,
- query: DeleteQuery,
-) -> GlobalResult {
- let CheckOutput { game_id, env_id } = ctx
- .auth()
- .check(
- ctx.op_ctx(),
- CheckOpts {
- query: &query.global,
- allow_service_token: true,
- opt_auth: false,
- },
- )
- .await?;
-
- ensure_with!(
- query.override_kill_timeout.unwrap_or(0) >= 0,
- API_BAD_QUERY_PARAMETER,
- parameter = "override_kill_timeout",
- error = "must be positive"
- );
- ensure_with!(
- query.override_kill_timeout.unwrap_or(0) < 2 * 60 * 60 * 1000,
- API_BAD_QUERY_PARAMETER,
- parameter = "override_kill_timeout",
- error = "cannot be longer than 2 hours"
- );
-
- let mut sub = ctx
- .subscribe::(("server_id", actor_id))
- .await?;
-
- // Get server after sub is created
- let server = assert::server_for_env(&ctx, actor_id, game_id, env_id, None).await?;
-
- // Already destroyed
- if server.destroy_ts.is_some() {
- return Ok(json!({}));
- }
-
- ctx.signal(ds::workflows::server::Destroy {
- override_kill_timeout_ms: query.override_kill_timeout,
- })
- .tag("server_id", actor_id)
- .send()
- .await?;
-
- sub.next().await?;
-
- Ok(json!({}))
-}
-
-pub async fn destroy_deprecated(
- ctx: Ctx,
- game_id: Uuid,
- env_id: Uuid,
- actor_id: Uuid,
- query: DeleteQuery,
-) -> GlobalResult {
- let global = build_global_query_compat(&ctx, game_id, env_id).await?;
- destroy(
- ctx,
- actor_id,
- DeleteQuery {
- global,
- override_kill_timeout: query.override_kill_timeout,
- },
- )
- .await
-}
-
-// MARK: POST /actors/{}/upgrade
-pub async fn upgrade(
- ctx: Ctx,
- actor_id: Uuid,
- body: models::ActorUpgradeActorRequest,
- query: GlobalQuery,
-) -> GlobalResult {
- let CheckOutput { game_id, env_id } = ctx
- .auth()
- .check(
- ctx.op_ctx(),
- CheckOpts {
- query: &query,
- allow_service_token: true,
- opt_auth: false,
- },
- )
- .await?;
-
- assert::server_for_env(&ctx, actor_id, game_id, env_id, None).await?;
-
- let build = resolve_build(&ctx, game_id, env_id, body.build, body.build_tags.flatten()).await?;
-
- // TODO: Add back once we figure out how to cleanly handle if a wf is already complete when
- // upgrading
- // let mut sub = ctx
- // .subscribe::(("server_id", actor_id))
- // .await?;
-
- ctx.signal(ds::workflows::server::Upgrade {
- image_id: build.build_id,
- })
- .tag("server_id", actor_id)
- .send()
- .await?;
-
- // sub.next().await?;
-
- Ok(json!({}))
-}
-
-// MARK: POST /actors/upgrade
-pub async fn upgrade_all(
- ctx: Ctx,
- body: models::ActorUpgradeAllActorsRequest,
- query: GlobalQuery,
-) -> GlobalResult {
- let CheckOutput { game_id, env_id } = ctx
- .auth()
- .check(
- ctx.op_ctx(),
- CheckOpts {
- query: &query,
- allow_service_token: true,
- opt_auth: false,
- },
- )
- .await?;
-
- let tags = unwrap_with!(body.tags, API_BAD_BODY, error = "missing property `tags`");
-
- ensure_with!(
- tags.as_object().map(|x| x.len()).unwrap_or_default() <= 8,
- API_BAD_BODY,
- error = "Too many tags (max 8)."
- );
-
- let tags = unwrap_with!(
- serde_json::from_value::>(tags).ok(),
- API_BAD_BODY,
- error = "`tags` must be `Map`"
- );
-
- for (k, v) in &tags {
- ensure_with!(
- !k.is_empty(),
- API_BAD_BODY,
- error = "tags[]: Tag label cannot be empty."
- );
- ensure_with!(
- k.len() <= 32,
- API_BAD_BODY,
- error = format!(
- "tags[{:?}]: Tag label too large (max 32 bytes).",
- util::safe_slice(k, 0, 32),
- ),
- );
- ensure_with!(
- !v.is_empty(),
- API_BAD_BODY,
- error = format!("tags[{k:?}]: Tag value cannot be empty.")
- );
- ensure_with!(
- v.len() <= 1024,
- API_BAD_BODY,
- error = format!("tags[{k:?}]: Tag value too large (max 1024 bytes)."),
- );
- }
-
- let build = resolve_build(&ctx, game_id, env_id, body.build, body.build_tags.flatten()).await?;
-
- // Work in batches
- let mut count = 0;
- let mut cursor = None;
- loop {
- let list_res = ctx
- .op(ds::ops::server::list_for_env::Input {
- env_id,
- tags: tags.clone(),
- include_destroyed: false,
- cursor,
- limit: 10_000,
- })
- .await?;
-
- count += list_res.server_ids.len();
- cursor = list_res.server_ids.last().cloned();
-
- // TODO: Add back once we figure out how to cleanly handle if a wf is already complete when
- // upgrading
- // let subs = futures_util::stream::iter(list_res.server_ids.clone())
- // .map(|server_id| {
- // ctx.subscribe::(("server_id", server_id))
- // })
- // .buffer_unordered(32)
- // .try_collect::>()
- // .await?;
-
- futures_util::stream::iter(list_res.server_ids)
- .map(|server_id| {
- ctx.signal(ds::workflows::server::Upgrade {
- image_id: build.build_id,
- })
- .tag("server_id", server_id)
- .send()
- })
- .buffer_unordered(32)
- .try_collect::>()
- .await?;
-
- // futures_util::stream::iter(subs)
- // .map(|mut sub| async move { sub.next().await })
- // .buffer_unordered(32)
- // .try_collect::>()
- // .await?;
-
- if count < 10_000 {
- break;
- }
- }
-
- Ok(models::ActorUpgradeAllActorsResponse {
- count: count.try_into()?,
- })
-}
-
-// MARK: GET /actors
-#[derive(Debug, Clone, Deserialize)]
-pub struct ListQuery {
- #[serde(flatten)]
- global_endpoint_type: GlobalEndpointTypeQuery,
- tags_json: Option,
- include_destroyed: Option,
- cursor: Option,
-}
-
-pub async fn list_actors(
- ctx: Ctx,
- watch_index: WatchIndexQuery,
- query: ListQuery,
-) -> GlobalResult {
- list_actors_inner(&ctx, watch_index, query).await
-}
-
-async fn list_actors_inner(
- ctx: &Ctx,
- _watch_index: WatchIndexQuery,
- query: ListQuery,
-) -> GlobalResult {
- let CheckOutput { env_id, .. } = ctx
- .auth()
- .check(
- ctx.op_ctx(),
- CheckOpts {
- query: &query.global_endpoint_type.global,
- allow_service_token: true,
- opt_auth: false,
- },
- )
- .await?;
-
- let include_destroyed = query.include_destroyed.unwrap_or(false);
-
- let tags = unwrap_with!(
- query
- .tags_json
- .as_deref()
- .map_or(Ok(HashMap::new()), serde_json::from_str)
- .ok(),
- API_BAD_QUERY_PARAMETER,
- parameter = "tags_json",
- error = "must be `Map`"
- );
-
- let list_res = ctx
- .op(ds::ops::server::list_for_env::Input {
- env_id,
- tags,
- include_destroyed,
- cursor: query.cursor,
- // HACK: Until we have webhooks, there needs to be a good way to get all of the most
- // recent crashed actors. 10k is a high limit intentionally.
- limit: if include_destroyed { 64 } else { 10_000 },
- })
- .await?;
-
- let servers_res = ctx
- .op(ds::ops::server::get::Input {
- server_ids: list_res.server_ids.clone(),
- endpoint_type: query
- .global_endpoint_type
- .endpoint_type
- .map(ApiInto::api_into),
- })
- .await?;
-
- let datacenter_ids = servers_res
- .servers
- .iter()
- .map(|s| s.datacenter_id)
- .collect::>()
- .into_iter()
- .collect::>();
- let dc_res = ctx
- .op(cluster::ops::datacenter::get::Input { datacenter_ids })
- .await?;
-
- let servers = servers_res
- .servers
- .into_iter()
- .map(|a| {
- let dc = unwrap!(dc_res
- .datacenters
- .iter()
- .find(|dc| dc.datacenter_id == a.datacenter_id));
- ds::types::convert_actor_to_api(a, &dc)
- })
- .collect::>>()?;
-
- Ok(models::ActorListActorsResponse { actors: servers })
-}
-
-pub async fn list_servers_deprecated(
- ctx: Ctx,
- game_id: Uuid,
- env_id: Uuid,
- watch_index: WatchIndexQuery,
- query: ListQuery,
-) -> GlobalResult {
- let global = build_global_query_compat(&ctx, game_id, env_id).await?;
- let actors_res = list_actors_inner(
- &ctx,
- watch_index,
- ListQuery {
- global_endpoint_type: GlobalEndpointTypeQuery {
- global,
- ..query.global_endpoint_type
- },
- ..query
- },
- )
- .await?;
-
- let clusters_res = ctx
- .op(cluster::ops::get_for_game::Input {
- game_ids: vec![game_id],
- })
- .await?;
- let cluster_id = unwrap!(clusters_res.games.first()).cluster_id;
-
- let dc_name_ids = actors_res
- .actors
- .iter()
- .map(|s| s.region.clone())
- .collect::>()
- .into_iter()
- .collect::>();
- let dc_resolve_res = ctx
- .op(cluster::ops::datacenter::resolve_for_name_id::Input {
- cluster_id,
- name_ids: dc_name_ids,
- })
- .await?;
-
- let dc_res = ctx
- .op(cluster::ops::datacenter::get::Input {
- datacenter_ids: dc_resolve_res
- .datacenters
- .iter()
- .map(|x| x.datacenter_id)
- .collect::>(),
- })
- .await?;
-
- Ok(models::ServersListServersResponse {
- servers: actors_res
- .actors
- .into_iter()
- .map(|a| {
- let dc = unwrap!(dc_res.datacenters.iter().find(|dc| dc.name_id == a.region));
- legacy_convert_actor_to_server(a, dc)
- })
- .collect::, _>>()?,
- })
-}
-
-fn legacy_convert_actor_to_server(
- a: models::ActorActor,
- datacenter: &cluster::types::Datacenter,
-) -> GlobalResult {
- Ok(models::ServersServer {
- created_at: a
- .created_at
- .parse::>()?
- .timestamp_millis(),
- datacenter: datacenter.datacenter_id,
- destroyed_at: a
- .destroyed_at
- .map(|ts| {
- GlobalResult::Ok(
- ts.parse::>()?
- .timestamp_millis(),
- )
- })
- .transpose()?,
- environment: Uuid::nil(),
- id: a.id,
- lifecycle: Box::new(models::ServersLifecycle {
- kill_timeout: a.lifecycle.kill_timeout,
- }),
- network: Box::new(models::ServersNetwork {
- mode: Some(match a.network.mode {
- models::ActorNetworkMode::Host => models::ServersNetworkMode::Host,
- models::ActorNetworkMode::Bridge => models::ServersNetworkMode::Bridge,
- }),
- ports: a
- .network
- .ports
- .into_iter()
- .map(|(k, p)| {
- (
- k,
- models::ServersPort {
- internal_port: p.internal_port,
- protocol: match p.protocol {
- models::ActorPortProtocol::Http => {
- models::ServersPortProtocol::Http
- }
- models::ActorPortProtocol::Https => {
- models::ServersPortProtocol::Https
- }
- models::ActorPortProtocol::Tcp => models::ServersPortProtocol::Tcp,
- models::ActorPortProtocol::TcpTls => {
- models::ServersPortProtocol::TcpTls
- }
- models::ActorPortProtocol::Udp => models::ServersPortProtocol::Udp,
- },
- public_hostname: p.hostname,
- public_port: p.port,
- routing: Box::new(models::ServersPortRouting {
- game_guard: p.routing.guard.map(|_| json!({})),
- host: p.routing.host.map(|_| json!({})),
- }),
- },
- )
- })
- .collect(),
- }),
- resources: Box::new(models::ServersResources {
- cpu: a.resources.cpu,
- memory: a.resources.memory,
- }),
- runtime: Box::new(models::ServersRuntime {
- arguments: a.runtime.arguments,
- build: a.runtime.build,
- environment: a.runtime.environment,
- }),
- started_at: a
- .started_at
- .map(|ts| {
- GlobalResult::Ok(
- ts.parse::>()?
- .timestamp_millis(),
- )
- })
- .transpose()?,
- tags: a.tags,
- })
-}
-
-async fn resolve_build(
- ctx: &Ctx,
- game_id: Uuid,
- env_id: Uuid,
- build_id: Option,
- build_tags: Option,
-) -> GlobalResult {
- match (build_id, build_tags) {
- (Some(build_id), None) => {
- let builds_res = ctx
- .op(build::ops::get::Input {
- build_ids: vec![build_id],
- })
- .await?;
- let build = unwrap_with!(builds_res.builds.into_iter().next(), BUILD_NOT_FOUND);
-
- // Ensure build belongs to this game/env
- if let Some(build_game_id) = build.game_id {
- ensure_with!(build_game_id == game_id, BUILD_NOT_FOUND);
- } else if let Some(build_env_id) = build.env_id {
- ensure_with!(build_env_id == env_id, BUILD_NOT_FOUND);
- }
-
- Ok(build)
- }
- // Resolve build from tags
- (None, Some(build_tags)) => {
- let build_tags = unwrap_with!(
- serde_json::from_value::>(build_tags).ok(),
- API_BAD_BODY,
- error = "`build_tags` must be `Map`"
- );
-
- ensure_with!(
- build_tags.len() < 8,
- API_BAD_BODY,
- error = "Too many build tags (max 8)."
- );
-
- for (k, v) in &build_tags {
- ensure_with!(
- !k.is_empty(),
- API_BAD_BODY,
- error = "build_tags[]: Build tag label cannot be empty."
- );
- ensure_with!(
- k.len() < 32,
- API_BAD_BODY,
- error = format!(
- "build_tags[{:?}]: Build tag label too large (max 32 bytes).",
- util::safe_slice(k, 0, 32),
- )
- );
- ensure_with!(
- !v.is_empty(),
- API_BAD_BODY,
- error = format!("build_tags[{k:?}]: Build tag value cannot be empty.")
- );
- ensure_with!(
- v.len() < 256,
- API_BAD_BODY,
- error =
- format!("build_tags[{k:?}]: Build tag value too large (max 256 bytes).")
- );
- }
-
- let builds_res = ctx
- .op(build::ops::resolve_for_tags::Input {
- env_id,
- tags: build_tags,
- })
- .await?;
-
- let build = unwrap_with!(
- builds_res.builds.into_iter().next(),
- BUILD_NOT_FOUND_WITH_TAGS
- );
-
- // Ensure build belongs to this game/env
- if let Some(build_game_id) = build.game_id {
- ensure_with!(build_game_id == game_id, BUILD_NOT_FOUND);
- } else if let Some(build_env_id) = build.env_id {
- ensure_with!(build_env_id == env_id, BUILD_NOT_FOUND);
- }
-
- Ok(build)
- }
- _ => {
- bail_with!(
- API_BAD_BODY,
- error = "must have either `build` or `build_tags`"
- );
- }
- }
-}
-
-async fn resolve_dc_id(
- ctx: &Ctx,
- cluster_id: Uuid,
- region: Option,
-) -> GlobalResult {
- if let Some(region) = region {
- let dcs_res = ctx
- .op(cluster::ops::datacenter::resolve_for_name_id::Input {
- cluster_id,
- name_ids: vec![region],
- })
- .await?;
- let dc = unwrap_with!(
- dcs_res.datacenters.first(),
- ACTOR_FAILED_TO_CREATE,
- error = "Region not found."
- );
-
- Ok(dc.datacenter_id)
- }
- // Auto-select the closest region
- else {
- let clusters_res = ctx
- .op(cluster::ops::datacenter::list::Input {
- cluster_ids: vec![cluster_id],
- })
- .await?;
- let cluster = unwrap!(clusters_res.clusters.first());
-
- if let Some((lat, long)) = ctx.coords() {
- let recommend_res = op!([ctx] region_recommend {
- region_ids: cluster
- .datacenter_ids
- .iter()
- .cloned()
- .map(Into::into)
- .collect(),
- coords: Some(backend::net::Coordinates {
- latitude: lat,
- longitude: long,
- }),
- ..Default::default()
- })
- .await?;
- let primary_region = unwrap!(recommend_res.regions.first());
- let primary_region_id = unwrap_ref!(primary_region.region_id).as_uuid();
-
- Ok(primary_region_id)
- } else {
- tracing::warn!("coords not provided to select region");
-
- let datacenter_id = *unwrap_with!(
- cluster.datacenter_ids.first(),
- ACTOR_FAILED_TO_CREATE,
- error = "No regions found."
- );
-
- Ok(datacenter_id)
- }
- }
-}
diff --git a/packages/api/actor/src/route/mod.rs b/packages/api/actor/src/route/mod.rs
deleted file mode 100644
index 599081c7f0..0000000000
--- a/packages/api/actor/src/route/mod.rs
+++ /dev/null
@@ -1,282 +0,0 @@
-use api_helper::{define_router, util::CorsConfigBuilder};
-use hyper::{Body, Request, Response};
-use rivet_api::models;
-use rivet_operation::prelude::*;
-use serde::Deserialize;
-use uuid::Uuid;
-
-pub mod actors;
-pub mod builds;
-pub mod logs;
-pub mod regions;
-
-#[derive(Debug, Clone, Deserialize)]
-pub struct GlobalQuery {
- /// Slug of the project.
- ///
- /// If provided, `environment` must also be provided.
- pub project: Option,
-
- /// Slug of the environment.
- pub environment: Option,
-}
-
-impl GlobalQuery {
- /// Returns both the project and environment.
- ///
- /// Validates that the project can only be specified with the environment.
- pub fn project_and_env(&self) -> GlobalResult<(Option<&str>, Option<&str>)> {
- if let Some(environment) = &self.environment {
- Ok((self.project.as_deref(), Some(environment)))
- } else {
- // Don't allow just the project
- if self.project.is_some() {
- bail_with!(
- API_BAD_QUERY,
- parameter = "project",
- error = "Must provide both `project` and `environment` query together."
- )
- } else {
- Ok((None, None))
- }
- }
- }
-}
-
-define_router! {
- cors: |config| CorsConfigBuilder::public().build(),
- routes: {
- "actors": {
- GET: actors::list_actors(
- query: actors::ListQuery,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- POST: actors::create(
- query: actors::GlobalEndpointTypeQuery,
- body: models::ActorCreateActorRequest,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 1_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "actors" / "upgrade": {
- POST: actors::upgrade_all(
- query: GlobalQuery,
- body: models::ActorUpgradeAllActorsRequest,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 1_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "actors" / Uuid: {
- GET: actors::get(
- query: actors::GlobalEndpointTypeQuery,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
-
- ),
- DELETE: actors::destroy(
- query: actors::DeleteQuery,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 10_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "actors" / Uuid / "upgrade": {
- POST: actors::upgrade(
- query: GlobalQuery,
- body: models::ActorUpgradeActorRequest,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 1_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "actors" / Uuid / "logs": {
- GET: logs::get_logs(
- query: logs::GetActorLogsQuery,
- opt_auth: true,
- ),
- },
-
-
- "builds": {
- GET: builds::list(
- query: builds::ListQuery,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "builds" / Uuid: {
- GET: builds::get(
- query: GlobalQuery,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "builds" / Uuid / "tags": {
- PATCH: builds::patch_tags(
- query: GlobalQuery,
- body: models::ActorPatchBuildTagsRequest,
- opt_auth: true,
- ),
- },
-
- "builds" / "prepare": {
- POST: builds::create_build(
- query: GlobalQuery,
- body: models::ActorPrepareBuildRequest,
- opt_auth: true,
- ),
- },
-
- "builds" / Uuid / "complete": {
- POST: builds::complete_build(
- query: GlobalQuery,
- body: serde_json::Value,
- opt_auth: true,
- ),
- },
-
- // MARK: Regions
- "regions": {
- GET: regions::list(
- query: GlobalQuery,
- opt_auth: true,
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
- "regions" / "resolve": {
- GET: regions::resolve(
- query: regions::ResolveQuery,
- opt_auth: true,
- ),
- },
-
- // MARK: Deprecated
- "games" / Uuid / "environments" / Uuid / "servers": {
- GET: actors::list_servers_deprecated(
- query: actors::ListQuery,
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- POST: actors::create_deprecated(
- body: models::ServersCreateServerRequest,
- rate_limit: {
- buckets: [
- { count: 1_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "games" / Uuid / "environments" / Uuid / "servers" / Uuid: {
- GET: actors::get_deprecated(
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
-
- ),
- DELETE: actors::destroy_deprecated(
- query: actors::DeleteQuery,
- rate_limit: {
- buckets: [
- { count: 10_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "games" / Uuid / "environments" / Uuid / "servers" / Uuid / "logs" : {
- GET: logs::get_logs_deprecated(
- query: logs::GetActorLogsQuery,
- ),
- },
-
- "games" / Uuid / "environments" / Uuid / "builds": {
- GET: builds::list_deprecated(
- query: builds::ListQuery,
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "games" / Uuid / "environments" / Uuid / "builds" / Uuid: {
- GET: builds::get_deprecated(
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
-
- "games" / Uuid / "environments" / Uuid / "builds" / Uuid / "tags": {
- PATCH: builds::patch_tags_deprecated(body: models::ServersPatchBuildTagsRequest),
- },
-
- "games" / Uuid / "environments" / Uuid / "builds" / "prepare": {
- POST: builds::create_build_deprecated(body: models::ServersCreateBuildRequest),
- },
-
- "games" / Uuid / "environments" / Uuid / "builds" / Uuid / "complete": {
- POST: builds::complete_build_deprecated(body: serde_json::Value),
- },
-
- "games" / Uuid / "environments" / Uuid / "datacenters": {
- GET: regions::list_deprecated(
- rate_limit: {
- buckets: [
- { count: 60_000, bucket: duration::minutes(1) },
- ],
- },
- ),
- },
- },
-}
diff --git a/packages/api/monolith-edge/Cargo.toml b/packages/api/monolith-edge/Cargo.toml
deleted file mode 100644
index bb47886f19..0000000000
--- a/packages/api/monolith-edge/Cargo.toml
+++ /dev/null
@@ -1,27 +0,0 @@
-[package]
-name = "api-monolith-edge"
-version.workspace = true
-authors.workspace = true
-license.workspace = true
-edition.workspace = true
-
-[dependencies]
-api-helper.workspace = true
-async-trait = "0.1"
-chirp-client.workspace = true
-http = "0.2"
-hyper = { version = "0.14", features = ["server", "http1", "tcp"] }
-rivet-operation.workspace = true
-tokio = { version = "1.40" }
-tracing = "0.1"
-tracing-subscriber = { version = "0.3", default-features = false, features = [
- "fmt",
- "json",
- "ansi",
-] }
-url = "2.2.2"
-
-api-traefik-provider.workspace = true
-api-provision.workspace = true
-rivet-config.workspace = true
-rivet-env.workspace = true
diff --git a/packages/api/monolith-edge/src/route/mod.rs b/packages/api/monolith-edge/src/route/mod.rs
deleted file mode 100644
index 2488ab2dc3..0000000000
--- a/packages/api/monolith-edge/src/route/mod.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use api_helper::define_router;
-use hyper::{Body, Request, Response};
-use rivet_operation::prelude::*;
-
-pub async fn handle(
- shared_client: chirp_client::SharedClientHandle,
- config: rivet_config::Config,
- pools: rivet_pools::Pools,
- cache: rivet_cache::Cache,
- ray_id: uuid::Uuid,
- request: Request,
-) -> Result, http::Error> {
- let response = Response::builder();
-
- // Handle route
- Router::handle(
- shared_client,
- config,
- pools,
- cache,
- ray_id,
- request,
- response,
- )
- .await
-}
-
-define_router! {
- routes: {},
- mounts: [
- {
- path: api_traefik_provider::route::Router,
- prefix: "traefik-provider",
- },
- {
- path: api_provision::route::Router,
- prefix: "provision",
- },
- ],
-}
diff --git a/packages/api/monolith-public/Cargo.toml b/packages/api/monolith-public/Cargo.toml
deleted file mode 100644
index c8918b0166..0000000000
--- a/packages/api/monolith-public/Cargo.toml
+++ /dev/null
@@ -1,37 +0,0 @@
-[package]
-name = "api-monolith-public"
-version.workspace = true
-authors.workspace = true
-license.workspace = true
-edition.workspace = true
-
-[dependencies]
-api-helper.workspace = true
-async-trait = "0.1"
-chirp-client.workspace = true
-http = "0.2"
-hyper = { version = "0.14", features = ["server", "http1", "tcp"] }
-rivet-operation.workspace = true
-tokio = { version = "1.40" }
-tracing = "0.1"
-tracing-subscriber = { version = "0.3", default-features = false, features = [
- "fmt",
- "json",
- "ansi",
-] }
-url = "2.2.2"
-
-api-actor.workspace = true
-api-auth.workspace = true
-api-cf-verification.workspace = true
-api-cloud.workspace = true
-api-games.workspace = true
-api-group.workspace = true
-api-identity.workspace = true
-api-job.workspace = true
-api-matchmaker.workspace = true
-api-portal.workspace = true
-api-status.workspace = true
-rivet-config.workspace = true
-rivet-env.workspace = true
-api-ui.workspace = true
diff --git a/packages/api/monolith-public/src/route/mod.rs b/packages/api/monolith-public/src/route/mod.rs
deleted file mode 100644
index 74e86447c4..0000000000
--- a/packages/api/monolith-public/src/route/mod.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use api_helper::define_router;
-use hyper::{Body, Request, Response};
-use rivet_operation::prelude::*;
-
-pub async fn handle(
- shared_client: chirp_client::SharedClientHandle,
- config: rivet_config::Config,
- pools: rivet_pools::Pools,
- cache: rivet_cache::Cache,
- ray_id: uuid::Uuid,
- request: Request,
-) -> Result, http::Error> {
- let response = Response::builder();
-
- // Handle route
- Router::handle(
- shared_client,
- config,
- pools,
- cache,
- ray_id,
- request,
- response,
- )
- .await
-}
-
-define_router! {
- routes: {},
- mounts: [
- {
- path: api_ui::route::Router,
- },
- {
- path: api_auth::route::Router,
- prefix: "auth",
- },
- {
- path: api_cf_verification::route::Router,
- prefix: "cf-verification",
- },
- {
- path: api_cloud::route::Router,
- prefix: "cloud",
- },
- {
- path: api_games::route::Router,
- },
- {
- path: api_group::route::Router,
- prefix: "group",
- },
- {
- path: api_identity::route::Router,
- prefix: "identity",
- },
- {
- path: api_job::route::Router,
- prefix: "job",
- },
- {
- path: api_matchmaker::route::Router,
- prefix: "matchmaker",
- },
- {
- path: api_portal::route::Router,
- prefix: "portal",
- },
- {
- path: api_status::route::Router,
- prefix: "status",
- },
- {
- path: api_actor::route::Router,
- },
- ],
-}
diff --git a/packages/api/provision/src/auth.rs b/packages/api/provision/src/auth.rs
deleted file mode 100644
index ce8e259174..0000000000
--- a/packages/api/provision/src/auth.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use api_helper::{
- auth::{ApiAuth, AuthRateLimitCtx},
- util::as_auth_expired,
-};
-use proto::claims::Claims;
-use rivet_claims::ClaimsDecode;
-use rivet_operation::prelude::*;
-
-/// Information derived from the authentication middleware.
-pub struct Auth {
- config: rivet_config::Config,
- claims: Option,
-}
-
-#[async_trait]
-impl ApiAuth for Auth {
- async fn new(
- config: rivet_config::Config,
- api_token: Option,
- rate_limit_ctx: AuthRateLimitCtx<'_>,
- ) -> GlobalResult {
- Self::rate_limit(&config, rate_limit_ctx).await?;
-
- Ok(Auth {
- config: config.clone(),
- claims: if let Some(api_token) = api_token {
- Some(as_auth_expired(rivet_claims::decode(
- &config.server()?.jwt.public,
- &api_token,
- )?)?)
- } else {
- None
- },
- })
- }
-
- async fn rate_limit(
- config: &rivet_config::Config,
- _rate_limit_ctx: AuthRateLimitCtx<'_>,
- ) -> GlobalResult<()> {
- Ok(())
- }
-}
-
-impl Auth {
- pub fn claims(&self) -> GlobalResult<&Claims> {
- self.claims
- .as_ref()
- .ok_or_else(|| err_code!(API_UNAUTHORIZED, reason = "No bearer token provided."))
- }
-
- pub fn server(&self) -> GlobalResult {
- self.claims()?.as_provisioned_server()
- }
-}
diff --git a/packages/api/traefik-provider/Cargo.toml b/packages/api/traefik-provider/Cargo.toml
deleted file mode 100644
index e7285ba4a2..0000000000
--- a/packages/api/traefik-provider/Cargo.toml
+++ /dev/null
@@ -1,64 +0,0 @@
-[package]
-name = "api-traefik-provider"
-version.workspace = true
-authors.workspace = true
-license.workspace = true
-edition.workspace = true
-
-[dependencies]
-rivet-convert.workspace = true
-api-helper.workspace = true
-async_once = "0.2"
-async-trait = "0.1"
-chirp-client.workspace = true
-rivet-operation.workspace = true
-chrono = "0.4"
-http = "0.2"
-hyper = { version = "0.14", features = ["server", "http1", "stream", "tcp"] }
-lazy_static = "1.4"
-prost = "0.10"
-rivet-cache.workspace = true
-rivet-claims.workspace = true
-rivet-health-checks.workspace = true
-rivet-pools.workspace = true
-s3-util.workspace = true
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-thiserror = "1.0"
-tokio = { version = "1.40" }
-tracing = "0.1"
-tracing-subscriber = { version = "0.3", default-features = false, features = [
- "fmt",
- "json",
- "ansi",
-] }
-url = "2.2.2"
-util-cdn.workspace = true
-util-job.workspace = true
-uuid = { version = "1", features = ["v4"] }
-
-cluster.workspace = true
-ds.workspace = true
-rivet-config.workspace = true
-rivet-env.workspace = true
-
-[dependencies.sqlx]
-workspace = true
-features = ["json"]
-
-
-[dev-dependencies]
-rivet-connection.workspace = true
-rivet-route.workspace = true
-base64 = "0.13"
-reqwest = "0.11"
-
-cdn-namespace-auth-user-update.workspace = true
-cdn-namespace-domain-create.workspace = true
-faker-cdn-site.workspace = true
-faker-game.workspace = true
-faker-game-namespace.workspace = true
-faker-game-version.workspace = true
-faker-job-run.workspace = true
-faker-region.workspace = true
-game-get.workspace = true
diff --git a/packages/api/traefik-provider/src/route/game_guard/mod.rs b/packages/api/traefik-provider/src/route/game_guard/mod.rs
deleted file mode 100644
index 1cef260432..0000000000
--- a/packages/api/traefik-provider/src/route/game_guard/mod.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-use api_helper::{anchor::WatchIndexQuery, ctx::Ctx};
-use dynamic_servers::build_ds;
-use job::build_job;
-use rivet_operation::prelude::*;
-use serde::{Deserialize, Serialize};
-
-use crate::{auth::Auth, types};
-
-pub mod dynamic_servers;
-pub mod job;
-
-#[derive(Debug, Serialize, Deserialize)]
-#[serde(deny_unknown_fields)]
-pub struct ConfigQuery {
- token: Option,
- datacenter: Uuid,
- server: Option,
-}
-
-#[tracing::instrument(skip(ctx))]
-pub async fn config(
- ctx: Ctx,
- _watch_index: WatchIndexQuery,
- ConfigQuery {
- token,
- datacenter,
- server,
- }: ConfigQuery,
-) -> GlobalResult {
- ctx.auth().token(&token).await?;
-
- // Fetch configs and catch any errors
- let mut config = types::TraefikConfigResponse::default();
- build_job(&ctx, datacenter, &mut config).await?;
- let latest_ds_create_ts = build_ds(&ctx, datacenter, server, &mut config).await?;
-
- // Publish message when the request is complete
- if let Some(latest_ds_create_ts) = latest_ds_create_ts {
- ctx.msg(ds::workflows::server::pegboard::TraefikPoll {
- server_id: server,
- latest_ds_create_ts,
- })
- .tag("datacenter_id", datacenter)
- .send()
- .await?;
- }
-
- tracing::debug!(
- http_services = ?config.http.services.len(),
- http_routers = config.http.routers.len(),
- http_middlewares = ?config.http.middlewares.len(),
- tcp_services = ?config.tcp.services.len(),
- tcp_routers = config.tcp.routers.len(),
- tcp_middlewares = ?config.tcp.middlewares.len(),
- udp_services = ?config.udp.services.len(),
- udp_routers = config.udp.routers.len(),
- udp_middlewares = ?config.udp.middlewares.len(),
- "traefik config"
- );
-
- Ok(types::TraefikConfigResponseNullified {
- http: config.http.nullified(),
- tcp: config.tcp.nullified(),
- udp: config.udp.nullified(),
- })
-}
diff --git a/packages/api/traefik-provider/src/route/mod.rs b/packages/api/traefik-provider/src/route/mod.rs
deleted file mode 100644
index 20fd4f3f6b..0000000000
--- a/packages/api/traefik-provider/src/route/mod.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use api_helper::define_router;
-use hyper::{Body, Request, Response};
-
-pub mod core;
-pub mod game_guard;
-pub mod tunnel;
-
-define_router! {
- routes: {
- "config" / "core": {
- GET: core::config(
- query: core::ConfigQuery,
- internal_endpoint: true,
- opt_auth: true,
- ),
- },
- "config" / "tunnel": {
- GET: tunnel::config(
- query: tunnel::ConfigQuery,
- internal_endpoint: true,
- opt_auth: true,
- ),
- },
- "config" / "game-guard": {
- GET: game_guard::config(
- query: game_guard::ConfigQuery,
- internal_endpoint: true,
- opt_auth: true,
- ),
- }
- }
-}
diff --git a/packages/common/api-helper/build/src/macro_util.rs b/packages/common/api-helper/build/src/macro_util.rs
index c78f97dc30..6fe74203f4 100644
--- a/packages/common/api-helper/build/src/macro_util.rs
+++ b/packages/common/api-helper/build/src/macro_util.rs
@@ -18,6 +18,8 @@ use crate::{
ctx::Ctx,
};
+pub type DefaultDbDriver = chirp_workflow::db::DatabaseCrdbNats;
+
pub mod __metrics {
pub use crate::metrics::*;
}
@@ -235,7 +237,10 @@ pub fn __deserialize_query(route: &Url) -> GlobalRes
}
#[doc(hidden)]
-pub async fn __with_ctx(
+pub async fn __with_ctx<
+ A: auth::ApiAuth + Send,
+ DB: chirp_workflow::db::Database + Sync + 'static,
+>(
shared_client: chirp_client::SharedClientHandle,
config: rivet_config::Config,
pools: rivet_pools::Pools,
@@ -342,7 +347,7 @@ pub async fn __with_ctx(
}],
);
let conn = rivet_connection::Connection::new(client, pools.clone(), cache.clone());
- let db = chirp_workflow::compat::db_from_pools(&pools).await?;
+ let db = DB::from_pools(pools.clone())?;
let internal_ctx = ApiCtx::new(
db,
config.clone(),
diff --git a/packages/common/api-helper/macros/src/lib.rs b/packages/common/api-helper/macros/src/lib.rs
index b9c244f2ad..095ea46ba3 100644
--- a/packages/common/api-helper/macros/src/lib.rs
+++ b/packages/common/api-helper/macros/src/lib.rs
@@ -39,6 +39,7 @@ struct EndpointRouter {
routes: Punctuated,
cors_config: Option,
mounts: Punctuated,
+ db_driver: Option,
}
impl Parse for EndpointRouter {
@@ -46,6 +47,7 @@ impl Parse for EndpointRouter {
let mut routes = None;
let mut cors_config = None;
let mut mounts = None;
+ let mut db_driver = None;
// Loop through all keys in the object
loop {
@@ -92,11 +94,21 @@ impl Parse for EndpointRouter {
));
}
}
+ "db_driver" => {
+ if db_driver.is_none() {
+ db_driver = Some(input.parse()?);
+ } else {
+ return Err(syn::Error::new(
+ key.span(),
+ format!("Duplicate key `{}`.", key),
+ ));
+ }
+ }
_ => {
return Err(syn::Error::new(
key.span(),
format!(
- "Unexpected key `{}`. Try `routes`, `cors`, or `mounts`.",
+ "Unexpected key `{}`. Try `routes`, `cors`, `mounts`, or `db_driver`.",
key
),
));
@@ -125,6 +137,7 @@ impl Parse for EndpointRouter {
routes,
cors_config,
mounts,
+ db_driver,
})
}
}
@@ -134,7 +147,7 @@ impl EndpointRouter {
let endpoints = self
.routes
.into_iter()
- .map(|endpoint| endpoint.render(self.cors_config.clone()))
+ .map(|endpoint| endpoint.render(self.cors_config.clone(), self.db_driver.clone()))
.collect::>>()?;
let mounts = self
@@ -466,7 +479,11 @@ impl Parse for Endpoint {
}
impl Endpoint {
- fn render(self, cors_config: Option) -> syn::Result {
+ fn render(
+ self,
+ cors_config: Option,
+ db_driver: Option,
+ ) -> syn::Result {
// Check cors at the endpoint level
let cors = if let Some(cors_config) = cors_config {
quote! {
@@ -530,7 +547,7 @@ impl Endpoint {
let arms = self
.functions
.into_iter()
- .map(|func| func.render(arg_list.clone(), metrics_path.clone()))
+ .map(|func| func.render(db_driver.clone(), arg_list.clone(), metrics_path.clone()))
.collect::>>()?;
Ok(quote! {
@@ -651,6 +668,7 @@ impl Parse for EndpointFunction {
impl EndpointFunction {
fn render(
self,
+ db_driver: Option,
mut arg_list: Vec,
metrics_path: Literal,
) -> syn::Result {
@@ -849,7 +867,7 @@ impl EndpointFunction {
arg_list.push(arg_name.to_token_stream());
Ok(quote! {
- let #arg_name = macro_util::__deserialize_query::<#value>(
+ let #arg_name = api_helper::macro_util::__deserialize_query::<#value>(
&router_config.route
)?;
})
@@ -858,7 +876,7 @@ impl EndpointFunction {
arg_list.push(arg_name.to_token_stream());
Ok(quote! {
- let #arg_name = macro_util::__deserialize_cookies(&request);
+ let #arg_name = api_helper::macro_util::__deserialize_cookies(&request);
})
} else if arg.label == "header" {
let value = arg.value.expect_expr()?;
@@ -872,7 +890,7 @@ impl EndpointFunction {
.unwrap_or_else(|| quote! { _ });
Ok(quote! {
- let #arg_name = macro_util::__deserialize_header::<#associated_type, _>(&request, #value)?;
+ let #arg_name = api_helper::macro_util::__deserialize_header::<#associated_type, _>(&request, #value)?;
})
} else {
// NOTE: This scope is not unreachable, certain arguments such as body or rate limit are
@@ -882,12 +900,18 @@ impl EndpointFunction {
})
.collect::>>()?;
+ let db_driver = if let Some(db_driver) = db_driver {
+ quote! { #db_driver }
+ } else {
+ quote! { api_helper::macro_util::DefaultDbDriver }
+ };
+
// Format single endpoint
Ok(quote! {
&http::Method::#req_type => {
#(#args)*
- let ctx = macro_util::__with_ctx(
+ let ctx = macro_util::__with_ctx::<_, #db_driver>(
shared_client.clone(),
config.clone(),
pools.clone(),
diff --git a/packages/common/chirp-workflow/core/src/compat.rs b/packages/common/chirp-workflow/core/src/compat.rs
index 2d1c8192f9..7f036ea763 100644
--- a/packages/common/chirp-workflow/core/src/compat.rs
+++ b/packages/common/chirp-workflow/core/src/compat.rs
@@ -12,9 +12,10 @@ use crate::{
message::{MessageCtx, SubscriptionHandle},
},
db::{Database, DatabaseCrdbNats, DatabaseHandle},
- message::{AsTags, Message},
+ message::Message,
operation::{Operation, OperationInput},
signal::Signal,
+ utils::tags::AsTags,
workflow::{Workflow, WorkflowInput},
};
@@ -119,9 +120,3 @@ async fn db_from_ctx(
.map(|db| db as DatabaseHandle)
.map_err(Into::into)
}
-
-pub async fn db_from_pools(pools: &rivet_pools::Pools) -> GlobalResult {
- DatabaseCrdbNats::from_pools(pools.clone())
- .map(|db| db as DatabaseHandle)
- .map_err(Into::into)
-}
diff --git a/packages/common/chirp-workflow/core/src/ctx/activity.rs b/packages/common/chirp-workflow/core/src/ctx/activity.rs
index ce4b9d4c30..f04bfc2aa1 100644
--- a/packages/common/chirp-workflow/core/src/ctx/activity.rs
+++ b/packages/common/chirp-workflow/core/src/ctx/activity.rs
@@ -9,8 +9,9 @@ use crate::{
},
db::DatabaseHandle,
error::WorkflowResult,
- message::{AsTags, Message, NatsMessage},
+ message::{Message, NatsMessage},
operation::{Operation, OperationInput},
+ utils::tags::AsTags,
};
#[derive(Clone)]
@@ -223,6 +224,21 @@ impl ActivityCtx {
self.conn.clickhouse().await
}
+ pub async fn fdb(&self) -> Result {
+ self.conn.fdb().await
+ }
+
+ /// Access the SQLite database for this workflow. This cannot access any other database.
+ pub async fn sqlite(&self) -> Result {
+ self.conn
+ .sqlite(format!("{}-data", self.workflow_id), false)
+ .await
+ }
+
+ pub async fn sqlite_for_workflow(&self, workflow_id: Uuid) -> GlobalResult {
+ common::sqlite_for_workflow(&self.db, &self.conn, workflow_id, false).await
+ }
+
// Backwards compatibility
pub fn op_ctx(&self) -> &rivet_operation::OperationContext<()> {
&self.op_ctx
diff --git a/packages/common/chirp-workflow/core/src/ctx/api.rs b/packages/common/chirp-workflow/core/src/ctx/api.rs
index 0e8be48ebd..b20e723ccf 100644
--- a/packages/common/chirp-workflow/core/src/ctx/api.rs
+++ b/packages/common/chirp-workflow/core/src/ctx/api.rs
@@ -11,9 +11,10 @@ use crate::{
},
db::DatabaseHandle,
error::WorkflowResult,
- message::{AsTags, Message, NatsMessage},
+ message::{Message, NatsMessage},
operation::{Operation, OperationInput},
signal::Signal,
+ utils::tags::AsTags,
workflow::{Workflow, WorkflowInput},
};
@@ -232,6 +233,10 @@ impl ApiCtx {
self.conn.clickhouse().await
}
+ pub async fn sqlite_for_workflow(&self, workflow_id: Uuid) -> GlobalResult {
+ common::sqlite_for_workflow(&self.db, &self.conn, workflow_id, true).await
+ }
+
// Backwards compatibility
pub fn op_ctx(&self) -> &rivet_operation::OperationContext<()> {
&self.op_ctx
diff --git a/packages/common/chirp-workflow/core/src/ctx/common.rs b/packages/common/chirp-workflow/core/src/ctx/common.rs
index 4f4bea8730..67e3394bb4 100644
--- a/packages/common/chirp-workflow/core/src/ctx/common.rs
+++ b/packages/common/chirp-workflow/core/src/ctx/common.rs
@@ -1,10 +1,13 @@
use std::time::Duration;
use global_error::{GlobalError, GlobalResult};
+use rivet_pools::prelude::*;
use uuid::Uuid;
+use crate::utils::tags::AsTags;
+
/// Poll interval when polling for a sub workflow in-process
-pub const SUB_WORKFLOW_RETRY: Duration = Duration::from_millis(500);
+pub const SUB_WORKFLOW_RETRY: Duration = Duration::from_millis(350);
/// Time to delay a workflow from retrying after an error
pub const RETRY_TIMEOUT_MS: usize = 2000;
pub const WORKFLOW_TIMEOUT: Duration = Duration::from_secs(60);
@@ -46,6 +49,16 @@ pub async fn wait_for_workflow(
.await?
}
+/// Finds the first workflow with the given tags.
+pub async fn find_workflow(
+ db: &DatabaseHandle,
+ tags: impl AsTags,
+) -> GlobalResult