Skip to content

Commit fa4adc9

Browse files
committed
Download musl toolchains in parallel
1 parent 9e9cb9d commit fa4adc9

File tree

2 files changed

+38
-24
lines changed

2 files changed

+38
-24
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ RUN apt install -y \
3434

3535
# Remove externally-managed constrainsts since we run inside a docker...
3636
RUN rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED
37-
RUN python3.12 -m pip install requests
37+
RUN python3.12 -m pip install aiohttp
3838

3939
COPY src/docker_utils/download_musl_toolchains.py .
4040
RUN python3.12 -u download_musl_toolchains.py

src/docker_utils/download_musl_toolchains.py

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
#!/usr/bin/env python3.12
22

3-
import requests
3+
from typing import List
4+
from pathlib import Path
5+
46
import tarfile
7+
import tempfile
58
import os
69
import shutil
10+
import asyncio
711

8-
from pathlib import Path
12+
import aiohttp
913

1014
ARCHS = {
1115
"x86_64" : "https://more.musl.cc/11/x86_64-linux-musl/x86_64-linux-musl-cross.tgz",
@@ -17,36 +21,46 @@
1721
}
1822
CHUNK_SIZE = 65536
1923
MUSL_TOOLCHAINS_DIR = Path("/musl-toolchains")
20-
ENTRYPOINT = "/entrypoint.sh"
21-
22-
def download_file(url: str, filename: str):
23-
print(f"Downloading {filename}")
24-
with requests.get(url, stream=True) as r:
25-
r.raise_for_status()
26-
with open(filename, "wb") as f:
27-
for chunk in r.iter_content(chunk_size=CHUNK_SIZE):
28-
f.write(chunk)
29-
print(f"{filename} downloaded.")
30-
31-
def extract_tarball(filename: str, dst: Path):
32-
print(f"Extracting {filename}")
33-
with tarfile.open(filename, "r:gz") as tar:
24+
ENTRYPOINT = Path("/entrypoint.sh")
25+
26+
async def download_file(url: str, filename: str):
27+
async with aiohttp.ClientSession() as session:
28+
async with session.get(url) as response:
29+
with open(filename, 'wb') as f:
30+
async for data in response.content.iter_chunked(CHUNK_SIZE):
31+
f.write(data)
32+
33+
def extract_tarfile(filename: str, dst: Path):
34+
with tarfile.open(filename, "r") as tar:
3435
tar.extractall(path=dst)
35-
print(f"{filename} extracted")
36+
37+
async def download_tarfile(tar_url: str, extraction_dir: Path):
38+
with tempfile.NamedTemporaryFile() as named_tempfile:
39+
await download_file(tar_url, named_tempfile.name)
40+
41+
# Tarfile extraction is still being done synchronously.
42+
extract_tarfile(named_tempfile.name, extraction_dir)
43+
44+
print(f"Downloaded & Extracted: {tar_url!r}")
45+
46+
async def download_archs() -> List[str]:
47+
print(f"Downloading toolchains for architectures: {', '.join(ARCHS.keys())}")
48+
49+
async with asyncio.TaskGroup() as tg:
50+
for url in ARCHS.values():
51+
tg.create_task(download_tarfile(url, MUSL_TOOLCHAINS_DIR))
3652

3753
def add_to_path(curr_path: str, package_path: Path):
3854
return curr_path + ":" + str((package_path / "bin").resolve())
3955

40-
4156
def main():
4257
os.mkdir(MUSL_TOOLCHAINS_DIR)
4358

59+
asyncio.run(download_archs())
60+
4461
updated_path = "$PATH"
45-
for arch, url in ARCHS.items():
46-
filename = url.split("/")[-1]
47-
download_file(url, filename)
48-
extract_tarball(filename, MUSL_TOOLCHAINS_DIR)
49-
updated_path = add_to_path(updated_path, MUSL_TOOLCHAINS_DIR / filename.removesuffix(".tgz"))
62+
for musl_arch_dir in os.scandir(MUSL_TOOLCHAINS_DIR):
63+
updated_path = add_to_path(updated_path, musl_arch_dir.path)
5064

5165
# Fix the x86_64 dynamic loader if needed:
5266
# Unfortunately, the internal gdb build scripts builds some binaries (that generate documentation)

0 commit comments

Comments
 (0)