-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This should help to track changes to the EC2 instance. This also moves over to use SQLAlchemy in storage.py rather than plain sqlite3.
- Loading branch information
Showing
9 changed files
with
362 additions
and
32 deletions.
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42
ci-based/alembic/versions/20230928_1204-311be9937d3e_add_machine_table.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
"""add machine table | ||
Revision ID: 311be9937d3e | ||
Revises: 1c1d18482b62 | ||
Create Date: 2023-09-28 12:04:49.205816 | ||
""" | ||
from collections.abc import Sequence | ||
|
||
import sqlalchemy as sa | ||
from alembic import op | ||
|
||
# revision identifiers, used by Alembic. | ||
revision: str = "311be9937d3e" | ||
down_revision: str | None = "1c1d18482b62" | ||
branch_labels: str | Sequence[str] | None = None | ||
depends_on: str | Sequence[str] | None = None | ||
|
||
|
||
def upgrade() -> None: | ||
op.create_table( | ||
"machines", | ||
sa.Column("id", sa.Integer, primary_key=True), | ||
sa.Column( | ||
"created_at", sa.DateTime, server_default=sa.text("(STRFTIME('%s'))") | ||
), | ||
sa.Column("dmi_sys_vendor", sa.Text), | ||
sa.Column("dmi_product_uuid", sa.Text), | ||
sa.Column("dmi_product_serial", sa.Text), | ||
sa.Column("dmi_board_asset_tag", sa.Text), | ||
sa.Column("os", sa.Text), | ||
sa.Column("architecture", sa.Text), | ||
sa.Column("cpu_model", sa.Text), | ||
sa.Column("mem_total_bytes", sa.Integer), | ||
) | ||
|
||
op.add_column("jobs", sa.Column("machine_id", sa.Integer)) | ||
|
||
|
||
def downgrade() -> None: | ||
op.drop_column("jobs", "machine_id") | ||
op.drop_table("machines") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
""" | ||
Collect information about the running machine. | ||
Requires access to /sys for some of the DMI information | ||
""" | ||
import logging | ||
import platform | ||
from pathlib import Path | ||
|
||
from . import models | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def read_sys_dmi_id_file( | ||
name: str, base_path: Path = Path("/sys/devices/virtual/dmi/id") | ||
) -> str: | ||
""" | ||
Read /sys/devices/virtual/dmi/id/{name} and return the content, stripped. | ||
""" | ||
try: | ||
return (base_path / name).read_text().strip() | ||
except FileNotFoundError as e: | ||
logger.warning("Could not open %s: %s", base_path / name, e) | ||
return "" | ||
|
||
|
||
def get_cpu_model(path: Path = Path("/proc/cpuinfo")): | ||
""" | ||
Seems platform.processor() isn't working well. | ||
Parse the first model name line out of /proc/cpuinfo | ||
model : 142 | ||
model name : Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz | ||
stepping : 12 | ||
""" | ||
with path.open() as f: | ||
for line in f: | ||
if line.startswith("model name"): | ||
return line.split(":", 1)[1].strip() | ||
|
||
return "" | ||
|
||
|
||
def get_mem_total_bytes(path: Path = Path("/proc/meminfo")): | ||
""" | ||
Parse /proc/meminfo for the MemTotal: line. | ||
MemTotal: 16073016 kB | ||
MemFree: 4273580 kB | ||
""" | ||
with path.open() as f: | ||
for line in f: | ||
if line.startswith("MemTotal:"): | ||
value = line.split(":", 1)[1] | ||
kb, suffix = value.strip().split(" ", 1) | ||
if suffix != "kB" or not kb.isnumeric(): | ||
raise Exception(f"Unexpected value ${kb} / {suffix}") | ||
return int(kb) * 1024 | ||
|
||
return 0 | ||
|
||
|
||
def get_machine() -> models.Machine: | ||
""" | ||
Collect information for this system/machine. | ||
""" | ||
kwargs = {} | ||
for k in ["sys_vendor", "product_uuid", "product_serial", "board_asset_tag"]: | ||
kwargs[f"dmi_{k}"] = read_sys_dmi_id_file(k) | ||
|
||
kwargs["os"] = platform.system() | ||
kwargs["architecture"] = platform.machine() | ||
kwargs["cpu_model"] = get_cpu_model() | ||
kwargs["mem_total_bytes"] = get_mem_total_bytes() | ||
|
||
return models.Machine(**kwargs) |
Oops, something went wrong.