fix(cloudflared): remove command override for LSIO images
Problem: linuxserver/code-server already binds to 0.0.0.0 by default. Adding any command: override (--bind-addr or --host) breaks the LSIO s6 init system with 'not found' errors. Changes: - _ensure_web_bind_address(): Skip LSIO images entirely (no command override needed). If an existing override is found, remove it. - New migration 2026_05_29_remove_lsio_command_override: Removes --bind-addr and --host command overrides from both DB templates and existing instance compose files on disk for LSIO images. - Fixed migration to use correct column name (compose_path) and check information_schema for column existence defensively. Quality gates: ruff clean
This commit is contained in:
@@ -5,6 +5,7 @@ Revises: 2026_05_29_fix_web_tool_bind_address
|
||||
Create Date: 2026-05-29 15:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence
|
||||
|
||||
from alembic import op
|
||||
@@ -33,9 +34,7 @@ def upgrade() -> None:
|
||||
for tool_id, compose_template in result:
|
||||
updated = compose_template.replace(
|
||||
"--bind-addr 0.0.0.0:8443", "--host 0.0.0.0"
|
||||
).replace(
|
||||
"--bind-addr", "--host 0.0.0.0"
|
||||
)
|
||||
).replace("--bind-addr", "--host 0.0.0.0")
|
||||
|
||||
conn.execute(
|
||||
sa.text("""
|
||||
@@ -46,7 +45,9 @@ def upgrade() -> None:
|
||||
{"compose_template": updated, "id": tool_id},
|
||||
)
|
||||
|
||||
print(f"Fixed code-server template ({tool_id}): replaced --bind-addr with --host")
|
||||
print(
|
||||
f"Fixed code-server template ({tool_id}): replaced --bind-addr with --host"
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
"""Remove broken command override from LSIO code-server templates
|
||||
|
||||
Revision ID: 2026_05_29_remove_lsio_command_override
|
||||
Revises: 2026_05_29_fix_code_server_bind_addr
|
||||
Create Date: 2026-05-29 15:05:00.000000
|
||||
|
||||
"""
|
||||
from collections.abc import Sequence
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "2026_05_29_remove_lsio_command_override"
|
||||
down_revision: str | None = "2026_05_29_fix_code_server_bind_addr"
|
||||
branch_labels: Sequence[str] | None = None
|
||||
depends_on: Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
|
||||
# Fix tool_types templates in DB
|
||||
result = conn.execute(
|
||||
sa.text("""
|
||||
SELECT id, compose_template
|
||||
FROM tool_types
|
||||
WHERE name = 'code-server'
|
||||
""")
|
||||
).fetchall()
|
||||
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
|
||||
for tool_id, compose_template in result:
|
||||
try:
|
||||
data = yaml.safe_load(compose_template)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if not data or "services" not in data:
|
||||
continue
|
||||
|
||||
modified = False
|
||||
for svc in data["services"].values():
|
||||
image = svc.get("image", "")
|
||||
if not image or "linuxserver" not in image:
|
||||
continue
|
||||
if "command" in svc:
|
||||
cmd = svc["command"]
|
||||
if "--bind-addr" in cmd or "--host" in cmd:
|
||||
del svc["command"]
|
||||
modified = True
|
||||
|
||||
if modified:
|
||||
updated = yaml.dump(data, default_flow_style=False)
|
||||
conn.execute(
|
||||
sa.text("""
|
||||
UPDATE tool_types
|
||||
SET compose_template = :compose_template
|
||||
WHERE id = :id
|
||||
"""),
|
||||
{"compose_template": updated, "id": tool_id},
|
||||
)
|
||||
print(f"Removed broken command override from LSIO template ({tool_id})")
|
||||
|
||||
# Fix existing instance compose files on disk
|
||||
# Use information_schema to check if compose_path column exists
|
||||
col_result = conn.execute(
|
||||
sa.text("""
|
||||
SELECT column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'tool_instances'
|
||||
AND column_name = 'compose_path'
|
||||
""")
|
||||
).fetchone()
|
||||
|
||||
if col_result:
|
||||
result = conn.execute(
|
||||
sa.text("""
|
||||
SELECT id, compose_path
|
||||
FROM tool_instances
|
||||
WHERE compose_path IS NOT NULL
|
||||
""")
|
||||
).fetchall()
|
||||
|
||||
for instance_id, compose_path in result:
|
||||
path = Path(compose_path)
|
||||
if not path.exists():
|
||||
continue
|
||||
try:
|
||||
content = path.read_text()
|
||||
data = yaml.safe_load(content)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if not data or "services" not in data:
|
||||
continue
|
||||
|
||||
modified = False
|
||||
for svc in data["services"].values():
|
||||
image = svc.get("image", "")
|
||||
if not image or "linuxserver" not in image:
|
||||
continue
|
||||
if "command" in svc:
|
||||
cmd = svc["command"]
|
||||
if "--bind-addr" in cmd or "--host" in cmd:
|
||||
del svc["command"]
|
||||
modified = True
|
||||
|
||||
if modified:
|
||||
path.write_text(yaml.dump(data, default_flow_style=False))
|
||||
print(
|
||||
f"Removed broken command override from instance compose "
|
||||
f"({instance_id})"
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
pass
|
||||
@@ -652,6 +652,21 @@ def _ensure_web_bind_address(compose_path: str, tool_type_name: str) -> None:
|
||||
if not image:
|
||||
continue
|
||||
|
||||
# LSIO images already bind to 0.0.0.0 — command override breaks s6 init
|
||||
if "linuxserver" in image:
|
||||
existing_command = service_config.get("command", "")
|
||||
if "--bind-addr" in existing_command or "--host" in existing_command:
|
||||
del service_config["command"]
|
||||
compose_file.write_text(
|
||||
yaml.dump(compose_data, default_flow_style=False)
|
||||
)
|
||||
logger.warning(
|
||||
"Removed broken command override from LSIO image: %s",
|
||||
existing_command,
|
||||
)
|
||||
return
|
||||
return
|
||||
|
||||
# Check if the image matches a known tool
|
||||
is_code_server = tool_type_name == "code-server" and (
|
||||
"code-server" in image or "coder" in image
|
||||
|
||||
Reference in New Issue
Block a user