-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.py
148 lines (121 loc) · 4.16 KB
/
build.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python3
#
# wireguard4netns
#
# Copyright (c) 2022-2023 Carnegie Mellon University
# SPDX-License-Identifier: MIT
#
import os
import shutil
import subprocess
import sys
import tarfile
import urllib.request
from pathlib import Path
from tempfile import TemporaryDirectory
GOLANG = "https://storage.googleapis.com/golang/go{}.linux-amd64.tar.gz"
GOLANG_VERSION = "1.19.4"
def build(*_setup_kwargs):
"""Build wireguard-go"""
dest = Path("src") / "wireguard4netns" / "wireguard-go"
if dest.exists():
print(f"{dest} already exists, skipping build")
return
go = shutil.which("go")
patch = shutil.which("patch")
assert patch is not None, "Could not find the `patch` executable"
# copy wireguard-go source into a temporary directory, patch and compile
with TemporaryDirectory() as tmp:
if go is None:
# fetch + extract go compiler
print(f"Downloading golang-v{GOLANG_VERSION}")
stream = urllib.request.urlopen(GOLANG.format(GOLANG_VERSION))
golang = tarfile.open(fileobj=stream, mode="r|gz")
golang.extractall(path=tmp)
go = str(Path(tmp, "go", "bin", "go").resolve())
print("Copying wireguard-go source")
tmp_root = Path(tmp, "wireguard-go")
shutil.copytree("wireguard-go", tmp_root)
# when building from a git checkout this ends up pointing at a
# non-existent path and we don't need it, so just clean it up.
gitlink = tmp_root.joinpath(".git")
if gitlink.exists():
gitlink.unlink()
# apply patch to disable SetMTU()/MTU() because wireguard-go won't be
# able to see the tuntap interface in the unprivileged network namespace
print("Patching wireguard-go source")
patchfile = Path("wireguard-go.patch")
subprocess.run([patch, "-p1"], stdin=patchfile.open(), cwd=tmp_root, check=True)
# to avoid downloading already cached modules
GOMODCACHE = subprocess.run(
[go, "env", "GOMODCACHE"], stdout=subprocess.PIPE, check=True
).stdout
env = dict(os.environ, GOPATH=str(Path(tmp).resolve()), GOMODCACHE=GOMODCACHE)
print("Building custom wireguard-go binary")
subprocess.run([go, "get", "-d"], cwd=tmp_root, env=env, check=True)
subprocess.run(
[
go,
"build",
"-o",
str(dest.resolve()),
"-ldflags=-s -w -X golang.zx2c4.com/wireguard/ipc.socketDirectory=.",
],
cwd=tmp_root,
env=env,
check=True,
)
def check_submodule():
# make sure wireguard-go submodule is initialized
sys.exit(0 if Path("wireguard-go", "LICENSE").exists() else 1)
def clean_dist():
"""clean up leftover files from old builds"""
dist = Path("dist")
for sdist in dist.glob("*.tar.gz"):
sdist.unlink()
for wheel in dist.glob("*.whl"):
wheel.unlink()
SCRIPT = """\
cd /tmp
curl {golang} --silent --location | tar -xz
export PATH="/tmp/go/bin:$PATH" HOME=/tmp
for py in {pythons}; do
"/opt/python/$py/bin/pip" wheel --no-deps --wheel-dir /tmp /dist/*.tar.gz
done
ls *.whl | xargs -n1 --verbose auditwheel repair --wheel-dir /dist
ls -al /dist
"""
def wheels():
"""Build wheels from the pypa/manylinux2014_x86_64 Docker container
Based on how setuptools-golang builds, but using a newer manylinux
container and hardcoded golang/python versions.
"""
golang = GOLANG.format(GOLANG_VERSION)
pythons = [
"cp37-cp37m",
"cp38-cp38",
"cp39-cp39",
"cp310-cp310",
"cp311-cp311",
]
dist = Path("dist")
subprocess.run(
[
"docker",
"run",
"--rm",
"--volume",
f"{dist.resolve()}:/dist:rw",
"--user",
f"{os.getuid()}:{os.getgid()}",
"quay.io/pypa/manylinux2014_x86_64:latest",
"bash",
"-o",
"pipefail",
"-euxc",
SCRIPT.format(golang=golang, pythons=" ".join(pythons)),
],
check=True,
)
if __name__ == "__main__":
build()