chore: upgrade the Litestream sidecar to 0.5.17 - #92
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 📝 WalkthroughWalkthroughThe Litestream service now uses version 0.5.17 and a singular S3 replica configuration. The restore-rehearsal documentation and compose smoke test now check for the ChangesLitestream upgrade
Priority: ⬇️ Low Merge Risk: 🟡 Moderate · up to The upgrade’s configuration is compatible, but its smoke check can pass without an S3 backup and its restore rehearsal can report success without restoring data. Correct both validation paths before relying on them. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
Terraform Validation Results
Pushed by: @OjasMor, Action: |
Terraform Plan ResultsStatus: ✅ Success Show Planterraform_data.cloudflare_custom_domain_gate: Refreshing state... [id=09b89c9b-996a-d28b-1f9c-08760a492dac]
terraform_data.sign_in_provider_gate: Refreshing state... [id=b29a3d55-0be5-fb92-10a9-027df10c4b75]
terraform_data.access_control_gate: Refreshing state... [id=2b965617-b42b-4b42-5ea5-a1c3c05f10be]
random_password.service_auth_secret_github_bot: Refreshing state... [id=none]
random_password.service_auth_secret_web: Refreshing state... [id=none]
random_password.service_auth_secret_slack_bot: Refreshing state... [id=none]
random_bytes.provider_accounts_encryption_key: Refreshing state...
random_password.image_callback_token_pepper: Refreshing state... [id=none]
random_password.service_auth_secret_linear_bot: Refreshing state... [id=none]
cloudflare_d1_database.main: Refreshing state... [id=f747a908-5c69-45a1-86ab-ceb5250cf5e0]
module.slack_kv[0].cloudflare_workers_kv_namespace.this: Refreshing state... [id=ab5c371c8bc04a938ff2f71809933aa0]
module.linear_kv[0].cloudflare_workers_kv_namespace.this: Refreshing state... [id=777f94c3595f4de680c256a4e5fc6653]
cloudflare_queue.slack_completion_delivery_dlq[0]: Refreshing state... [id=396865e4939b4160937b2dc9ad5dabe1]
module.github_kv[0].cloudflare_workers_kv_namespace.this: Refreshing state... [id=e0848d433a4f466cafd4ed5d140aad7d]
cloudflare_r2_bucket.media: Refreshing state... [id=open-inspect-media-codos]
cloudflare_queue.image_build_finalization: Refreshing state... [id=a0647323f7424e778b9d59da50dc55cf]
cloudflare_queue.github_autofix_dlq[0]: Refreshing state... [id=3a27213aeba149d4b7cbf2d3551842f8]
cloudflare_queue.github_autofix[0]: Refreshing state... [id=033a23f13783415385b2f8799416c20f]
cloudflare_queue.slack_completion_delivery[0]: Refreshing state... [id=247b1100bac2408684d6a75c1bca0d28]
module.session_index_kv.cloudflare_workers_kv_namespace.this: Refreshing state... [id=ea0a253d5cb64d75a841acb88040cd2f]
cloudflare_queue.image_build_finalization_dlq: Refreshing state... [id=61535c686d8546099cfddcf39833572b]
local_file.web_app_wrangler_production[0]: Refreshing state... [id=cd7918121eb3c2c13074f16fa9e61f598c949663]
null_resource.github_bot_build[0]: Refreshing state... [id=3519361165849487687]
null_resource.control_plane_build: Refreshing state... [id=7644485588554403813]
data.external.modal_source_hash[0]: Reading...
module.modal_app[0].null_resource.modal_secrets[0]: Refreshing state... [id=8477737195823217344]
null_resource.linear_bot_build[0]: Refreshing state... [id=1758390259548583470]
null_resource.slack_bot_build[0]: Refreshing state... [id=4797908824648682639]
null_resource.web_app_cloudflare_build[0]: Refreshing state... [id=2874415199067689696]
module.linear_bot_worker[0].cloudflare_worker.this: Refreshing state... [id=049cd48117bc48b9b4332683a97d0a0e]
module.slack_bot_worker[0].cloudflare_worker.this: Refreshing state... [id=375c2c6875904657bce05c62c8048c76]
data.external.modal_source_hash[0]: Read complete after 0s [id=-]
module.modal_app[0].null_resource.modal_deploy: Refreshing state... [id=6679213070169677129]
null_resource.d1_migrations: Refreshing state... [id=263751651589333239]
module.slack_bot_worker[0].cloudflare_worker_version.this: Refreshing state... [id=8eefd5fb-667d-43f8-badb-9be44981cb74]
module.linear_bot_worker[0].cloudflare_worker_version.this: Refreshing state... [id=ab1388ca-fa95-43b5-954a-4a88df0865d9]
module.linear_bot_worker[0].cloudflare_workers_deployment.this: Refreshing state... [id=81811475-67bc-4c13-8fdd-306b74897a4c]
module.slack_bot_worker[0].cloudflare_workers_deployment.this: Refreshing state... [id=1d6573da-85d6-4a55-9695-d72c74394ed1]
module.control_plane_worker.cloudflare_worker.this: Refreshing state... [id=3457352971a74b89be5ed3700db48a8e]
cloudflare_queue_consumer.slack_completion_delivery[0]: Refreshing state...
module.control_plane_worker.cloudflare_worker_version.this: Refreshing state... [id=949cf845-c44e-43aa-bfdb-081f2062ed40]
module.control_plane_worker.cloudflare_workers_deployment.this: Refreshing state... [id=503512c8-3a87-4de4-b3e1-b61f691fddc2]
module.control_plane_worker.cloudflare_workers_cron_trigger.this[0]: Refreshing state... [id=open-inspect-control-plane-codos]
cloudflare_queue_consumer.image_build_finalization: Refreshing state...
module.github_bot_worker[0].cloudflare_worker.this: Refreshing state... [id=fa832fd890a14336bc3c63305e9bc36f]
null_resource.web_app_cloudflare_deploy[0]: Refreshing state... [id=202921713362885539]
null_resource.web_app_cloudflare_secrets[0]: Refreshing state... [id=8981633407656564074]
module.github_bot_worker[0].cloudflare_worker_version.this: Refreshing state... [id=c0559dc9-2c70-4269-91f1-bc21e0c0d66e]
module.github_bot_worker[0].cloudflare_workers_deployment.this: Refreshing state... [id=f4347343-cfac-4b9e-8529-f1da16deabeb]
cloudflare_queue_consumer.github_autofix[0]: Refreshing state...
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
~ update in-place
-/+ destroy and then create replacement
Terraform will perform the following actions:
# local_file.web_app_wrangler_production[0] will be created
+ resource "local_file" "web_app_wrangler_production" {
+ content = <<-EOT
name = "open-inspect-web-codos"
main = ".open-next/worker.js"
compatibility_date = "2025-08-15"
compatibility_flags = ["nodejs_compat", "global_fetch_strictly_public"]
# A custom-domain deployment has one canonical browser origin.
workers_dev = true
[vars]
CONTROL_PLANE_URL = "https://open-inspect-control-plane-codos.opencodos.workers.dev"
NEXT_PUBLIC_WS_URL = "wss://open-inspect-control-plane-codos.opencodos.workers.dev"
NEXT_PUBLIC_SANDBOX_PROVIDER = "modal"
NEXT_PUBLIC_APP_NAME = "Open-Inspect"
NEXT_PUBLIC_APP_ICON_URL = ""
[assets]
directory = ".open-next/assets"
binding = "ASSETS"
[[services]]
binding = "CONTROL_PLANE_WORKER"
service = "open-inspect-control-plane-codos"
EOT
+ content_base64sha256 = (known after apply)
+ content_base64sha512 = (known after apply)
+ content_md5 = (known after apply)
+ content_sha1 = (known after apply)
+ content_sha256 = (known after apply)
+ content_sha512 = (known after apply)
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "../../..//packages/web/wrangler.production.toml"
+ id = (known after apply)
}
# null_resource.control_plane_build must be replaced
-/+ resource "null_resource" "control_plane_build" {
~ id = "7644485588554403813" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-09-29T16:55:51Z" -> (known after apply)
}
}
# null_resource.github_bot_build[0] must be replaced
-/+ resource "null_resource" "github_bot_build" {
~ id = "3519361165849487687" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-09-29T16:55:51Z" -> (known after apply)
}
}
# null_resource.linear_bot_build[0] must be replaced
-/+ resource "null_resource" "linear_bot_build" {
~ id = "1758390259548583470" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-09-29T16:55:51Z" -> (known after apply)
}
}
# null_resource.slack_bot_build[0] must be replaced
-/+ resource "null_resource" "slack_bot_build" {
~ id = "4797908824648682639" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-09-29T16:55:51Z" -> (known after apply)
}
}
# null_resource.web_app_cloudflare_build[0] must be replaced
-/+ resource "null_resource" "web_app_cloudflare_build" {
~ id = "2874415199067689696" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-09-29T16:55:51Z" -> (known after apply)
}
}
# null_resource.web_app_cloudflare_deploy[0] must be replaced
-/+ resource "null_resource" "web_app_cloudflare_deploy" {
~ id = "202921713362885539" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-09-29T16:58:30Z" -> (known after apply)
}
}
# module.control_plane_worker.cloudflare_worker.this will be updated in-place
~ resource "cloudflare_worker" "this" {
id = "3457352971a74b89be5ed3700db48a8e"
name = "open-inspect-control-plane-codos"
~ observability = {
~ logs = {
+ destinations = (known after apply)
# (4 unchanged attributes hidden)
}
~ traces = {
+ destinations = (known after apply)
# (3 unchanged attributes hidden)
}
# (2 unchanged attributes hidden)
}
~ references = {
~ dispatch_namespace_outbounds = [] -> (known after apply)
~ domains = [] -> (known after apply)
~ durable_objects = [
- {
- namespace_id = "34735ba6d2804d67a82cf0bdf5a3175f" -> null
- namespace_name = "open-inspect-control-plane-codos_SessionDO" -> null
- worker_id = "3457352971a74b89be5ed3700db48a8e" -> null
- worker_name = "open-inspect-control-plane-codos" -> null
},
] -> (known after apply)
~ queues = [
- {
- queue_consumer_id = "4e24da4810c84b3e9e80ea014860d145" -> null
- queue_id = "033a23f13783415385b2f8799416c20f" -> null
- queue_name = "open-inspect-github-autofix-codos" -> null
},
- {
- queue_consumer_id = "f37fe99c4658470aa36767dfb68c3d6f" -> null
- queue_id = "a0647323f7424e778b9d59da50dc55cf" -> null
- queue_name = "open-inspect-image-build-finalization-codos" -> null
},
] -> (known after apply)
~ workers = [
- {
- id = "7aa4fa7a556a48708d1ebd7bbba3263a" -> null
- name = "open-inspect-web-codos" -> null
},
- {
- id = "fa832fd890a14336bc3c63305e9bc36f" -> null
- name = "open-inspect-github-bot-codos" -> null
},
- {
- id = "049cd48117bc48b9b4332683a97d0a0e" -> null
- name = "open-inspect-linear-bot-codos" -> null
},
- {
- id = "375c2c6875904657bce05c62c8048c76" -> null
- name = "open-inspect-slack-bot-codos" -> null
},
] -> (known after apply)
} -> (known after apply)
tags = []
~ updated_on = "2026-09-29T16:58:26Z" -> (known after apply)
# (6 unchanged attributes hidden)
}
# module.control_plane_worker.cloudflare_worker_version.this must be replaced
-/+ resource "cloudflare_worker_version" "this" {
~ annotations = {
+ workers_message = (known after apply)
+ workers_tag = (known after apply)
~ workers_triggered_by = "create_version_api" -> (known after apply)
} -> (known after apply)
~ bindings = (sensitive value) # forces replacement
~ created_on = "2026-09-29T16:58:27Z" -> (known after apply)
~ id = "949cf845-c44e-43aa-bfdb-081f2062ed40" -> (known after apply)
+ limits = (known after apply)
+ main_script_base64 = (known after apply)
~ migration_tag = "v1" -> (known after apply)
~ number = 68 -> (known after apply)
~ source = "terraform" -> (known after apply)
~ startup_time_ms = 229 -> (known after apply)
~ urls = [] -> (known after apply)
# (7 unchanged attributes hidden)
}
# module.control_plane_worker.cloudflare_workers_deployment.this must be replaced
-/+ resource "cloudflare_workers_deployment" "this" {
~ annotations = {
+ workers_message = (known after apply)
~ workers_triggered_by = "deployment" -> (known after apply)
} -> (known after apply)
+ author_email = (known after apply)
~ created_on = "2026-09-29T16:58:30Z" -> (known after apply)
~ id = "503512c8-3a87-4de4-b3e1-b61f691fddc2" -> (known after apply)
~ source = "terraform" -> (known after apply)
~ versions = [ # forces replacement
~ {
~ version_id = "949cf845-c44e-43aa-bfdb-081f2062ed40" -> (known after apply)
# (1 unchanged attribute hidden)
},
]
# (3 unchanged attributes hidden)
}
# module.github_bot_worker[0].cloudflare_worker.this will be updated in-place
~ resource "cloudflare_worker" "this" {
id = "fa832fd890a14336bc3c63305e9bc36f"
name = "open-inspect-github-bot-codos"
~ observability = {
~ logs = {
+ destinations = (known after apply)
# (4 unchanged attributes hidden)
}
~ traces = {
+ destinations = (known after apply)
# (3 unchanged attributes hidden)
}
# (2 unchanged attributes hidden)
}
~ references = {
~ dispatch_namespace_outbounds = [] -> (known after apply)
~ domains = [] -> (known after apply)
~ durable_objects = [] -> (known after apply)
~ queues = [] -> (known after apply)
~ workers = [
- {
- id = "3457352971a74b89be5ed3700db48a8e" -> null
- name = "open-inspect-control-plane-codos" -> null
},
] -> (known after apply)
} -> (known after apply)
tags = []
~ updated_on = "2026-09-29T16:58:30Z" -> (known after apply)
# (6 unchanged attributes hidden)
}
# module.github_bot_worker[0].cloudflare_worker_version.this must be replaced
-/+ resource "cloudflare_worker_version" "this" {
~ annotations = {
+ workers_message = (known after apply)
+ workers_tag = (known after apply)
~ workers_triggered_by = "create_version_api" -> (known after apply)
} -> (known after apply)
~ bindings = (sensitive value) # forces replacement
~ created_on = "2026-09-29T16:58:31Z" -> (known after apply)
~ id = "c0559dc9-2c70-4269-91f1-bc21e0c0d66e" -> (known after apply)
+ limits = (known after apply)
+ main_script_base64 = (known after apply)
+ migration_tag = (known after apply)
~ number = 66 -> (known after apply)
~ source = "terraform" -> (known after apply)
~ startup_time_ms = 77 -> (known after apply)
~ urls = [
- "https://c0559dc9-open-inspect-github-bot-codos.opencodos.workers.dev",
] -> (known after apply)
# (7 unchanged attributes hidden)
}
# module.github_bot_worker[0].cloudflare_workers_deployment.this must be replaced
-/+ resource "cloudflare_workers_deployment" "this" {
~ annotations = {
+ workers_message = (known after apply)
~ workers_triggered_by = "deployment" -> (known after apply)
} -> (known after apply)
+ author_email = (known after apply)
~ created_on = "2026-09-29T16:58:31Z" -> (known after apply)
~ id = "f4347343-cfac-4b9e-8529-f1da16deabeb" -> (known after apply)
~ source = "terraform" -> (known after apply)
~ versions = [ # forces replacement
~ {
~ version_id = "c0559dc9-2c70-4269-91f1-bc21e0c0d66e" -> (known after apply)
# (1 unchanged attribute hidden)
},
]
# (3 unchanged attributes hidden)
}
# module.linear_bot_worker[0].cloudflare_worker.this will be updated in-place
~ resource "cloudflare_worker" "this" {
id = "049cd48117bc48b9b4332683a97d0a0e"
name = "open-inspect-linear-bot-codos"
~ observability = {
~ logs = {
+ destinations = (known after apply)
# (4 unchanged attributes hidden)
}
~ traces = {
+ destinations = (known after apply)
# (3 unchanged attributes hidden)
}
# (2 unchanged attributes hidden)
}
~ references = {
~ dispatch_namespace_outbounds = [] -> (known after apply)
~ domains = [] -> (known after apply)
~ durable_objects = [] -> (known after apply)
~ queues = [] -> (known after apply)
~ workers = [
- {
- id = "3457352971a74b89be5ed3700db48a8e" -> null
- name = "open-inspect-control-plane-codos" -> null
},
] -> (known after apply)
} -> (known after apply)
tags = []
~ updated_on = "2026-09-29T16:55:52Z" -> (known after apply)
# (6 unchanged attributes hidden)
}
# module.linear_bot_worker[0].cloudflare_worker_version.this must be replaced
-/+ resource "cloudflare_worker_version" "this" {
~ annotations = {
+ workers_message = (known after apply)
+ workers_tag = (known after apply)
~ workers_triggered_by = "create_version_api" -> (known after apply)
} -> (known after apply)
~ bindings = (sensitive value) # forces replacement
~ created_on = "2026-09-29T16:55:53Z" -> (known after apply)
~ id = "ab1388ca-fa95-43b5-954a-4a88df0865d9" -> (known after apply)
+ limits = (known after apply)
+ main_script_base64 = (known after apply)
+ migration_tag = (known after apply)
~ number = 72 -> (known after apply)
~ source = "terraform" -> (known after apply)
~ startup_time_ms = 107 -> (known after apply)
~ urls = [
- "https://ab1388ca-open-inspect-linear-bot-codos.opencodos.workers.dev",
] -> (known after apply)
# (7 unchanged attributes hidden)
}
# module.linear_bot_worker[0].cloudflare_workers_deployment.this must be replaced
-/+ resource "cloudflare_workers_deployment" "this" {
~ annotations = {
+ workers_message = (known after apply)
~ workers_triggered_by = "deployment" -> (known after apply)
} -> (known after apply)
+ author_email = (known after apply)
~ created_on = "2026-09-29T16:55:54Z" -> (known after apply)
~ id = "81811475-67bc-4c13-8fdd-306b74897a4c" -> (known after apply)
~ source = "terraform" -> (known after apply)
~ versions = [ # forces replacement
~ {
~ version_id = "ab1388ca-fa95-43b5-954a-4a88df0865d9" -> (known after apply)
# (1 unchanged attribute hidden)
},
]
# (3 unchanged attributes hidden)
}
# module.slack_bot_worker[0].cloudflare_worker.this will be updated in-place
~ resource "cloudflare_worker" "this" {
id = "375c2c6875904657bce05c62c8048c76"
name = "open-inspect-slack-bot-codos"
~ observability = {
~ logs = {
+ destinations = (known after apply)
# (4 unchanged attributes hidden)
}
~ traces = {
+ destinations = (known after apply)
# (3 unchanged attributes hidden)
}
# (2 unchanged attributes hidden)
}
~ references = {
~ dispatch_namespace_outbounds = [] -> (known after apply)
~ domains = [] -> (known after apply)
~ durable_objects = [] -> (known after apply)
~ queues = [
- {
- queue_consumer_id = "767c5dfe751c4852a536d98b836cdd94" -> null
- queue_id = "247b1100bac2408684d6a75c1bca0d28" -> null
- queue_name = "open-inspect-slack-completion-codos" -> null
},
] -> (known after apply)
~ workers = [
- {
- id = "3457352971a74b89be5ed3700db48a8e" -> null
- name = "open-inspect-control-plane-codos" -> null
},
] -> (known after apply)
} -> (known after apply)
tags = []
~ updated_on = "2026-09-29T16:55:52Z" -> (known after apply)
# (6 unchanged attributes hidden)
}
# module.slack_bot_worker[0].cloudflare_worker_version.this must be replaced
-/+ resource "cloudflare_worker_version" "this" {
~ annotations = {
+ workers_message = (known after apply)
+ workers_tag = (known after apply)
~ workers_triggered_by = "create_version_api" -> (known after apply)
} -> (known after apply)
~ bindings = (sensitive value) # forces replacement
~ created_on = "2026-09-29T16:55:53Z" -> (known after apply)
~ id = "8eefd5fb-667d-43f8-badb-9be44981cb74" -> (known after apply)
+ limits = (known after apply)
+ main_script_base64 = (known after apply)
+ migration_tag = (known after apply)
~ number = 70 -> (known after apply)
~ source = "terraform" -> (known after apply)
~ startup_time_ms = 112 -> (known after apply)
~ urls = [
- "https://8eefd5fb-open-inspect-slack-bot-codos.opencodos.workers.dev",
] -> (known after apply)
# (7 unchanged attributes hidden)
}
# module.slack_bot_worker[0].cloudflare_workers_deployment.this must be replaced
-/+ resource "cloudflare_workers_deployment" "this" {
~ annotations = {
+ workers_message = (known after apply)
~ workers_triggered_by = "deployment" -> (known after apply)
} -> (known after apply)
+ author_email = (known after apply)
~ created_on = "2026-09-29T16:55:54Z" -> (known after apply)
~ id = "1d6573da-85d6-4a55-9695-d72c74394ed1" -> (known after apply)
~ source = "terraform" -> (known after apply)
~ versions = [ # forces replacement
~ {
~ version_id = "8eefd5fb-667d-43f8-badb-9be44981cb74" -> (known after apply)
# (1 unchanged attribute hidden)
},
]
# (3 unchanged attributes hidden)
}
Plan: 15 to add, 4 to change, 14 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: tfplan
To perform exactly these actions, run the following command to apply:
terraform apply "tfplan"Pushed by: @OjasMor |
There was a problem hiding this comment.
Blocking: 0 · Non-blocking: 0
The sidecar version and single-replica configuration match the restore image and Litestream 0.5's configuration contract. The log check now waits for the new message, and the Compose smoke check passed in CI. No actionable findings.
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Team
Run ID: 3b3f0b5d-d28b-4eb4-a6f1-bd7211606ce4
📒 Files selected for processing (4)
docker-compose.ymldocs/CONTROL_PLANE_CONTAINER.mdpackages/control-plane/docker/litestream.ymlscripts/compose-smoke.sh
Included review availability: This review used your included allowance. 2 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour. Your free on-demand review promotion remains active until October 9, 2026 at 6:00 PM UTC.
Supersedes #84.
What
The control-plane image has restored with Litestream 0.5.17 since #45, but the compose sidecar that writes the replica was still 0.3.13. This moves the sidecar to 0.5.17 so the reader and the writer run the same version.
docker-compose.yml: sidecar image0.3.13→0.5.17.litestream.yml: thereplicas:list becomes a singlereplica:. 0.5 prefers this form and rejects more than one replica per database. The bucket, thecontrol-plane/global.dbpath and every other setting are unchanged.compose-smoke.sh: 0.5 logssnapshot complete, neversnapshot written. The replication check now polls for the new line with a 60 s deadline instead of grepping once.CONTROL_PLANE_CONTAINER.md: the two log-line references are updated.Verified
snapshot complete2 s after start. That run later failed at attachment upload, because the local SeaweedFS ran out of disk on the Docker VM. This PR's CI smoke runs it on a clean runner.Rollout (manual, per AWS environment)
s3://<backup bucket>/control-plane/to a frozen prefix, and take an EBS snapshot of the data volume.terraform applyon aws-staging, restart the stack, and confirmdocker compose logs litestream | grep "snapshot complete".To roll back, restore the old image tag. 0.3 cannot read 0.5's LTX files, so a rollback after new writes needs the frozen copy from step 1.
🤖 Generated with Claude Code
Summary by CodeRabbit