installer v1 (C+D): Windows EXE installer trio + build script + local Hub E2E
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
"""Local E2E hub for Phase D — Windows installer against a real HTTP Hub.
|
||||
|
||||
Boots the control plane against a scratch SQLite DB, seeds a tenant + admin,
|
||||
publishes the real built EXE as release 1.1.1, creates a PENDING enrollment,
|
||||
generates an install code, then serves uvicorn on 127.0.0.1:PORT.
|
||||
|
||||
The operator/Setup CLI then runs against this local Hub. Usage:
|
||||
|
||||
python scripts/e2e_local_hub.py --port 8901 --exe dist/installer/GTIFiscalAgent-Setup-1.1.1.exe
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import dataclasses
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(ROOT))
|
||||
sys.path.insert(0, str(ROOT / "central"))
|
||||
|
||||
from central.app import config, enrollment # noqa: E402
|
||||
from central.app.models import AgentEnrollment, Tenant # noqa: E402
|
||||
from central.scripts.publish_agent_release import publish # noqa: E402
|
||||
from central.tests.test_control_plane import create_admin, seed # noqa: E402
|
||||
from sqlalchemy import select
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--port", type=int, default=8765)
|
||||
parser.add_argument("--exe", default=str(ROOT / "dist/installer/GTIFiscalAgent-Setup-1.1.1.exe"))
|
||||
args = parser.parse_args()
|
||||
|
||||
workdir = Path(tempfile.mkdtemp(prefix="gti_e2e_hub_"))
|
||||
print(f"[e2e] workdir={workdir}")
|
||||
|
||||
replaced = dataclasses.replace(
|
||||
config.settings,
|
||||
agent_release_storage_path=str(workdir / "releases"),
|
||||
base_url=f"http://127.0.0.1:{args.port}",
|
||||
web_cookie_secure=False,
|
||||
)
|
||||
config.settings = replaced
|
||||
if "app.config" in sys.modules:
|
||||
sys.modules["app.config"].settings = replaced
|
||||
|
||||
url = f"sqlite:///{workdir / 'e2e_hub.db'}"
|
||||
os.environ["DATABASE_URL"] = url
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.pool import StaticPool
|
||||
|
||||
from central.app.models import Base
|
||||
|
||||
engine = create_engine(url, connect_args={"check_same_thread": False}, poolclass=StaticPool)
|
||||
Base.metadata.create_all(engine)
|
||||
factory = sessionmaker(bind=engine, expire_on_commit=False)
|
||||
|
||||
seed(factory)
|
||||
|
||||
with factory() as session:
|
||||
data = Path(args.exe)
|
||||
if not data.exists():
|
||||
print(f"[e2e] EXE artefact not found: {data}", file=sys.stderr)
|
||||
return 2
|
||||
release, _created = publish(session, data, version="1.1.1")
|
||||
release_id = release.id
|
||||
print(f"[e2e] published release {release.version} id={release_id}")
|
||||
|
||||
tenant = session.scalars(select(Tenant).limit(1)).first()
|
||||
enr = AgentEnrollment(enrollment_uuid=str(uuid.uuid4()), tenant_id=tenant.id,
|
||||
display_name="Servidor E2E LOCAL", release_id=release_id, status="PENDING")
|
||||
session.add(enr)
|
||||
session.flush()
|
||||
|
||||
code = enrollment.generate_install_code()
|
||||
enr.install_code_hash = enrollment.install_code_digest(code)
|
||||
enr.install_code_expires_at = datetime.now(timezone.utc) + timedelta(seconds=86400)
|
||||
enr.install_code_created_at = datetime.now(timezone.utc)
|
||||
session.commit()
|
||||
print(f"[e2e] enrollment_uuid={enr.enrollment_uuid}", flush=True)
|
||||
print(f"[e2e] INSTALL_CODE={code}", flush=True)
|
||||
(workdir / "install_code.txt").write_text(code)
|
||||
(workdir / "enrollment_uuid.txt").write_text(enr.enrollment_uuid)
|
||||
print(f"[e2e] workdir={workdir}", flush=True)
|
||||
|
||||
import uvicorn
|
||||
|
||||
from central.app.main import create_app
|
||||
|
||||
app = create_app(database_probe=lambda: True, session_factory=factory, bootstrap_token=None)
|
||||
print(f"[e2e] serving hub on http://127.0.0.1:{args.port}")
|
||||
uvicorn.run(app, host="127.0.0.1", port=args.port, log_level="info")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user