-
Notifications
You must be signed in to change notification settings - Fork 3
/
artifact_docker_reorg.py
executable file
·74 lines (59 loc) · 2.33 KB
/
artifact_docker_reorg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python3
import argparse
import os
import re
import shutil
import sys
import tempfile
from pathlib import Path, PurePath
_ARM_PATTERN = re.compile(r'arm(?P<version>v\d)')
def docker_target_platform(platform: str) -> PurePath:
"""
Given an artifact platform suffix, e.g. linux-armv6, returns the Docker
TARGETPLATFORM identifier, e.g. linux/arm/v6.
:param platform: The platform section of an archive name, e.g. linux-armv6,
windows-amd64.
:return: The a directory hierarchy for the platform compatible with Docker,
e.g. linux/arm/v6 and windows/amd64 respectively.
"""
os, rest = platform.split('-', 1)
pieces = [os]
match = _ARM_PATTERN.fullmatch(rest)
if match:
pieces.extend(['arm', match.group('version')])
else:
pieces.append(rest)
return PurePath(*pieces)
def unpack(archive: Path, base_output: Path) -> None:
"""
Extracts an archive to the correct subdirectory under an output path.
:param archive: Path of the archive to extract. Anything supported by
shutil.unpack_archive() will work.
:param base_output: The root parent directory to extract to. Directories
will be created within this as necessary, e.g.
linux/arm/v6.
"""
inner_dir = archive.name.rstrip('.tar.gz')
_, platform = inner_dir.rsplit('.', 1)
final_dir = base_output / docker_target_platform(platform)
with tempfile.TemporaryDirectory() as tmp_dir:
tmp_dir = Path(tmp_dir)
shutil.unpack_archive(archive, tmp_dir)
shutil.move(tmp_dir / inner_dir, final_dir)
def _parse_args(argv: [str]) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description='Untars Linux archives to appropriate directories for Docker buildx.')
parser.add_argument('output', help='Root path to move binaries to')
parser.add_argument('input', help='Root path to read archives from')
return parser.parse_args(argv[1:])
def main(argv: [str]) -> int:
ns = _parse_args(argv)
output = Path(ns.output)
for entry in os.listdir(ns.input):
path = os.path.join(ns.input, entry)
if not os.path.isfile(path):
continue
unpack(Path(path), output)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))