-
Notifications
You must be signed in to change notification settings - Fork 0
Add git mirror hosting to cc-catalog-svc for air-gapped deployments #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
102ecdc
4df73c1
1230e61
beac696
5252940
cacceb0
5e0d962
09c5a4f
053235e
ffdd304
25063c3
be3224d
c7a63c2
50920bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,7 @@ | |
| from contextlib import contextmanager | ||
| from typing import Iterator | ||
|
|
||
| from sqlalchemy import create_engine, event | ||
| from sqlalchemy import create_engine, event, inspect, text | ||
| from sqlalchemy.engine import Engine | ||
| from sqlalchemy.orm import Session, sessionmaker | ||
|
|
||
|
|
@@ -32,6 +32,18 @@ | |
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
| # Columns added after the initial schema cut. ``init_db`` ensures these | ||
| # exist on already-deployed databases without requiring a full Alembic | ||
| # pipeline. Format: {table_name: {column_name: SQL type for ADD COLUMN}}. | ||
| # Keep types portable across sqlite + postgres (no ``SERIAL`` etc.). | ||
| _LEGACY_COLUMN_ADDITIONS: dict[str, dict[str, str]] = { | ||
| "codecollections": { | ||
| "git_head_commit": "VARCHAR(80)", | ||
| "git_last_synced": "TIMESTAMP", | ||
| "git_last_sync_error": "TEXT", | ||
| }, | ||
| } | ||
|
|
||
| _engine: Engine | None = None | ||
| _SessionLocal: sessionmaker[Session] | None = None | ||
|
|
||
|
|
@@ -79,17 +91,49 @@ def get_session_factory() -> sessionmaker[Session]: | |
|
|
||
|
|
||
| def init_db() -> None: | ||
| """Create all tables. Idempotent. | ||
|
|
||
| We intentionally use `Base.metadata.create_all` rather than Alembic | ||
| for the first cut: the schema is small (5 tables), single-writer | ||
| (the scheduler), and the service is greenfield. When the schema | ||
| starts evolving we'll add Alembic; until then `create_all` keeps the | ||
| bootstrap path trivial. | ||
| """Create all tables and apply lightweight in-place migrations. | ||
|
|
||
| We intentionally use ``Base.metadata.create_all`` rather than | ||
| Alembic for the first cut: the schema is small (5 tables), | ||
| single-writer (the scheduler), and the service is greenfield. When | ||
| the schema starts evolving in earnest we'll add Alembic. | ||
|
|
||
| ``create_all`` only creates *missing* tables, so any column added | ||
| to an existing table after the initial release would silently fail | ||
| on upgrade. ``_apply_legacy_column_additions`` patches that gap by | ||
| issuing ``ALTER TABLE ... ADD COLUMN IF NOT EXISTS`` (sqlite + pg | ||
| compatible) for every column registered in | ||
| ``_LEGACY_COLUMN_ADDITIONS``. | ||
| """ | ||
| engine = get_engine() | ||
| logger.info("initializing schema on %s", _safe_dsn(str(engine.url))) | ||
| Base.metadata.create_all(engine) | ||
| _apply_legacy_column_additions(engine) | ||
|
|
||
|
|
||
| def _apply_legacy_column_additions(engine: Engine) -> None: | ||
| """Idempotently add columns introduced after the initial schema.""" | ||
| inspector = inspect(engine) | ||
| existing_tables = set(inspector.get_table_names()) | ||
| for table_name, columns in _LEGACY_COLUMN_ADDITIONS.items(): | ||
| if table_name not in existing_tables: | ||
| # create_all just made it, so every column is already there. | ||
| continue | ||
| present = {c["name"] for c in inspector.get_columns(table_name)} | ||
| missing = {name: ddl for name, ddl in columns.items() if name not in present} | ||
| if not missing: | ||
| continue | ||
| with engine.begin() as conn: | ||
| for col_name, col_ddl in missing.items(): | ||
| logger.info( | ||
| "init_db: adding missing column %s.%s (%s)", | ||
| table_name, | ||
| col_name, | ||
| col_ddl, | ||
| ) | ||
| conn.execute( | ||
| text(f'ALTER TABLE {table_name} ADD COLUMN {col_name} {col_ddl}') | ||
| ) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Parallel startup column migration raceMedium Severity Legacy git column migration uses plain Reviewed by Cursor Bugbot for commit ffdd304. Configure here. |
||
|
|
||
|
|
||
| @contextmanager | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| """Git smart HTTP serving for mirrored bare repositories.""" | ||
|
|
||
| from app.git_http.server import ( | ||
| is_valid_slug, | ||
| list_bare_repo_slugs, | ||
| make_git_wsgi_app, | ||
| repo_bare_path, | ||
| repo_exists, | ||
| ) | ||
|
|
||
| __all__ = [ | ||
| "is_valid_slug", | ||
| "list_bare_repo_slugs", | ||
| "make_git_wsgi_app", | ||
| "repo_bare_path", | ||
| "repo_exists", | ||
| ] |


Uh oh!
There was an error while loading. Please reload this page.