speedup of build import
This commit is contained in:
parent
b6d3986660
commit
3a8be70f79
1 changed files with 37 additions and 43 deletions
|
@ -13,6 +13,9 @@ BUILDBOT_URL = "https://lab.llvm.org/buildbot/api/v2/"
|
||||||
# TODO(kuhnel): retry on connection issues, maybe resuse
|
# TODO(kuhnel): retry on connection issues, maybe resuse
|
||||||
# https://github.com/google/llvm-premerge-checks/blob/main/scripts/phabtalk/phabtalk.py#L44
|
# https://github.com/google/llvm-premerge-checks/blob/main/scripts/phabtalk/phabtalk.py#L44
|
||||||
|
|
||||||
|
# TODO(kuhnel): Import the step data so we can figure out in which step a build fails
|
||||||
|
# (e.g. compile vs. test)
|
||||||
|
|
||||||
|
|
||||||
def connect_to_db() -> psycopg2.extensions.connection:
|
def connect_to_db() -> psycopg2.extensions.connection:
|
||||||
"""Connect to the database, create tables as needed."""
|
"""Connect to the database, create tables as needed."""
|
||||||
|
@ -43,12 +46,14 @@ def create_tables(conn: psycopg2.extensions.connection):
|
||||||
ON buildbot_workers
|
ON buildbot_workers
|
||||||
(timestamp);"""
|
(timestamp);"""
|
||||||
)
|
)
|
||||||
|
# Note: step_data is not yet populated with data!
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"""CREATE TABLE IF NOT EXISTS buildbot_builds (
|
"""CREATE TABLE IF NOT EXISTS buildbot_builds (
|
||||||
|
build_id integer PRIMARY KEY,
|
||||||
builder_id integer NOT NULL,
|
builder_id integer NOT NULL,
|
||||||
build_number integer NOT NULL,
|
build_number integer NOT NULL,
|
||||||
build_data jsonb NOT NULL,
|
build_data jsonb NOT NULL,
|
||||||
step_data jsonb NOT NULL
|
step_data jsonb
|
||||||
);"""
|
);"""
|
||||||
)
|
)
|
||||||
cur.execute(
|
cur.execute(
|
||||||
|
@ -117,58 +122,47 @@ def get_builders() -> List[int]:
|
||||||
return [builder["builderid"] for builder in response.json()["builders"]]
|
return [builder["builderid"] for builder in response.json()["builders"]]
|
||||||
|
|
||||||
|
|
||||||
def get_last_build(builder_id: int, conn) -> int:
|
def get_last_build(conn) -> int:
|
||||||
"""Get the latest build number for a builder.
|
"""Get the latest build number for a builder.
|
||||||
|
|
||||||
This is used to only get new builds."""
|
This is used to only get new builds."""
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute(
|
cur.execute("SELECT MAX(build_id) FROM buildbot_builds")
|
||||||
"SELECT MAX(build_number) FROM buildbot_builds WHERE builder_id = %s;",
|
|
||||||
[builder_id],
|
|
||||||
)
|
|
||||||
row = cur.fetchone()
|
row = cur.fetchone()
|
||||||
if row is None or row[0] is None:
|
if row is None or row[0] is None:
|
||||||
return 0
|
return 0
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
|
|
||||||
def add_build(builder: int, number: int, build: str, steps: str, conn):
|
def get_build_status(conn: psycopg2.extensions.connection):
|
||||||
|
start_id = get_last_build(conn)
|
||||||
|
print("Updating build results, starting with {}...".format(start_id))
|
||||||
|
url = BUILDBOT_URL + "builds"
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
cur.execute(
|
|
||||||
"""INSERT INTO buildbot_builds
|
|
||||||
(builder_id, build_number, build_data,step_data)
|
|
||||||
values (%s,%s,%s,%s);""",
|
|
||||||
(
|
|
||||||
builder,
|
|
||||||
number,
|
|
||||||
json.dumps(build, sort_keys=True),
|
|
||||||
json.dumps(steps, sort_keys=True),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
for result_set in rest_request_iterator(
|
||||||
def update_build_status(conn: psycopg2.extensions.connection):
|
url, "builds", "buildid", start_id=start_id
|
||||||
print("Updating build results...")
|
):
|
||||||
# import only builds we have not yet stores in the database
|
args_str = b",".join(
|
||||||
for builder in get_builders():
|
cur.mogrify(
|
||||||
url = BUILDBOT_URL + "builders/{}/builds?number__gt={}".format(
|
b" (%s,%s,%s,%s) ",
|
||||||
builder, get_last_build(builder, conn)
|
(
|
||||||
|
build["buildid"],
|
||||||
|
build["builderid"],
|
||||||
|
build["number"],
|
||||||
|
json.dumps(build, sort_keys=True),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
for build in result_set
|
||||||
|
if build["complete"]
|
||||||
)
|
)
|
||||||
response = requests.get(url)
|
|
||||||
print(" builder {}".format(builder))
|
cur.execute(
|
||||||
# process builds in increasing order so we can resume the import process
|
b"INSERT INTO buildbot_builds (build_id, builder_id, build_number, build_data) values "
|
||||||
# if anything goes wrong
|
+ args_str
|
||||||
for build in sorted(response.json()["builds"], key=lambda b: b["number"]):
|
)
|
||||||
number = build["number"]
|
print(" {}".format(result_set[-1]["buildid"]))
|
||||||
# only store completed builds. Otherwise we would have to update them
|
conn.commit()
|
||||||
# after they are completed.
|
|
||||||
if not build["complete"]:
|
|
||||||
continue
|
|
||||||
steps = requests.get(
|
|
||||||
BUILDBOT_URL + "builders/{}/builds/{}/steps".format(builder, number)
|
|
||||||
).json()
|
|
||||||
add_build(builder, number, build, steps, conn)
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def rest_request_iterator(
|
def rest_request_iterator(
|
||||||
|
@ -285,9 +279,9 @@ def buildbot_monitoring():
|
||||||
"""Main function of monitoring the phabricator server."""
|
"""Main function of monitoring the phabricator server."""
|
||||||
conn = connect_to_db()
|
conn = connect_to_db()
|
||||||
create_tables(conn)
|
create_tables(conn)
|
||||||
# update_worker_status(conn)
|
update_worker_status(conn)
|
||||||
# update_build_status(conn)
|
get_build_status(conn)
|
||||||
# get_buildsets(conn)
|
get_buildsets(conn)
|
||||||
get_buildrequests(conn)
|
get_buildrequests(conn)
|
||||||
print("Completed, exiting...")
|
print("Completed, exiting...")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue