2024-04-19 12:24:50 +00:00
|
|
|
import os
|
|
|
|
import time
|
|
|
|
import shutil
|
|
|
|
import stat
|
|
|
|
import requests
|
|
|
|
import platform
|
2024-04-25 06:24:58 +00:00
|
|
|
from enum import Enum, unique
|
2024-04-19 12:24:50 +00:00
|
|
|
|
|
|
|
from utility.utils import is_windows_platform, wait_until
|
|
|
|
|
2024-04-25 03:25:05 +00:00
|
|
|
# v1.0.0-ci release
|
|
|
|
GITHUB_DOWNLOAD_URL="https://api.github.com/repos/0glabs/0g-storage-node/releases/152560136"
|
|
|
|
|
2024-04-23 06:35:24 +00:00
|
|
|
CONFLUX_BINARY = "conflux.exe" if is_windows_platform() else "conflux"
|
2024-04-25 03:25:05 +00:00
|
|
|
BSC_BINARY = "geth.exe" if is_windows_platform() else "geth"
|
2024-05-17 08:29:23 +00:00
|
|
|
ZG_BINARY = "0gchaind.exe" if is_windows_platform() else "0gchaind"
|
2024-04-23 06:35:24 +00:00
|
|
|
CLIENT_BINARY = "0g-storage-client.exe" if is_windows_platform() else "0g-storage-client"
|
|
|
|
|
2024-05-17 08:29:23 +00:00
|
|
|
ZG_GIT_REV = "7bc25a060fab9c17bc9942b6747cd07a668d3042" # v0.1.0
|
2024-06-10 14:54:39 +00:00
|
|
|
CLI_GIT_REV = "98d74b7e7e6084fc986cb43ce2c66692dac094a6"
|
2024-04-23 06:35:24 +00:00
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
@unique
|
|
|
|
class BuildBinaryResult(Enum):
|
|
|
|
AlreadyExists = 0
|
|
|
|
Installed = 1
|
|
|
|
NotInstalled = 2
|
|
|
|
|
|
|
|
def build_conflux(dir: str) -> BuildBinaryResult:
|
2024-04-25 03:25:05 +00:00
|
|
|
# Download or build conflux binary if absent
|
2024-04-25 06:24:58 +00:00
|
|
|
result = __download_from_github(
|
2024-04-25 03:25:05 +00:00
|
|
|
dir=dir,
|
|
|
|
binary_name=CONFLUX_BINARY,
|
|
|
|
github_url=GITHUB_DOWNLOAD_URL,
|
|
|
|
asset_name=__asset_name(CONFLUX_BINARY, zip=True),
|
2024-04-25 06:24:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if result == BuildBinaryResult.AlreadyExists or result == BuildBinaryResult.Installed:
|
|
|
|
return result
|
2024-04-25 03:25:05 +00:00
|
|
|
|
|
|
|
return __build_from_github(
|
2024-04-19 12:24:50 +00:00
|
|
|
dir=dir,
|
2024-04-23 06:35:24 +00:00
|
|
|
binary_name=CONFLUX_BINARY,
|
2024-04-19 12:24:50 +00:00
|
|
|
github_url="https://github.com/Conflux-Chain/conflux-rust.git",
|
|
|
|
build_cmd="cargo build --release --bin conflux",
|
|
|
|
compiled_relative_path=["target", "release"],
|
|
|
|
)
|
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
def build_bsc(dir: str) -> BuildBinaryResult:
|
2024-04-25 03:25:05 +00:00
|
|
|
# Download bsc binary if absent
|
2024-04-25 06:24:58 +00:00
|
|
|
result = __download_from_github(
|
2024-04-19 12:24:50 +00:00
|
|
|
dir=dir,
|
2024-04-25 03:25:05 +00:00
|
|
|
binary_name=BSC_BINARY,
|
2024-04-19 12:24:50 +00:00
|
|
|
github_url="https://api.github.com/repos/bnb-chain/bsc/releases/79485895",
|
2024-04-25 03:25:05 +00:00
|
|
|
asset_name=__asset_name(BSC_BINARY),
|
2024-04-19 12:24:50 +00:00
|
|
|
)
|
|
|
|
|
2024-04-25 03:25:05 +00:00
|
|
|
# Requires to download binary successfully, since it is not ready to build
|
|
|
|
# binary from source code.
|
2024-04-25 06:24:58 +00:00
|
|
|
assert result != BuildBinaryResult.NotInstalled, "Cannot download binary from github [%s]" % BSC_BINARY
|
2024-04-25 03:25:05 +00:00
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
return result
|
2024-04-25 03:25:05 +00:00
|
|
|
|
2024-05-17 08:29:23 +00:00
|
|
|
def build_zg(dir: str) -> BuildBinaryResult:
|
|
|
|
# Download or build 0gchain binary if absent
|
2024-04-25 06:24:58 +00:00
|
|
|
result = __download_from_github(
|
2024-04-25 03:25:05 +00:00
|
|
|
dir=dir,
|
2024-05-17 08:29:23 +00:00
|
|
|
binary_name=ZG_BINARY,
|
2024-04-25 03:25:05 +00:00
|
|
|
github_url=GITHUB_DOWNLOAD_URL,
|
2024-05-17 08:29:23 +00:00
|
|
|
asset_name=__asset_name(ZG_BINARY, zip=True),
|
2024-04-25 06:24:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if result == BuildBinaryResult.AlreadyExists or result == BuildBinaryResult.Installed:
|
|
|
|
return result
|
2024-04-25 03:25:05 +00:00
|
|
|
|
|
|
|
return __build_from_github(
|
2024-04-19 12:24:50 +00:00
|
|
|
dir=dir,
|
2024-05-17 08:29:23 +00:00
|
|
|
binary_name=ZG_BINARY,
|
|
|
|
github_url="https://github.com/0glabs/0g-chain.git",
|
|
|
|
git_rev=ZG_GIT_REV,
|
|
|
|
build_cmd="make install; cp $(go env GOPATH)/bin/0gchaind .",
|
2024-04-19 12:24:50 +00:00
|
|
|
compiled_relative_path=[],
|
|
|
|
)
|
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
def build_cli(dir: str) -> BuildBinaryResult:
|
2024-04-23 06:35:24 +00:00
|
|
|
# Build 0g-storage-client binary if absent
|
2024-04-25 03:25:05 +00:00
|
|
|
return __build_from_github(
|
2024-04-23 06:35:24 +00:00
|
|
|
dir=dir,
|
|
|
|
binary_name=CLIENT_BINARY,
|
|
|
|
github_url="https://github.com/0glabs/0g-storage-client.git",
|
|
|
|
git_rev=CLI_GIT_REV,
|
|
|
|
build_cmd="go build",
|
|
|
|
compiled_relative_path=[],
|
|
|
|
)
|
2024-04-19 12:24:50 +00:00
|
|
|
|
2024-04-25 03:25:05 +00:00
|
|
|
def __asset_name(binary_name: str, zip: bool = False) -> str:
|
|
|
|
sys = platform.system().lower()
|
|
|
|
if sys == "linux":
|
|
|
|
return f"{binary_name}_linux.zip" if zip else f"{binary_name}_linux"
|
|
|
|
elif sys == "windows":
|
|
|
|
binary_name = binary_name.removesuffix(".exe")
|
|
|
|
return f"{binary_name}_windows.zip" if zip else f"{binary_name}_windows.exe"
|
|
|
|
elif sys == "darwin":
|
|
|
|
return f"{binary_name}_mac.zip" if zip else f"{binary_name}_mac"
|
|
|
|
else:
|
|
|
|
raise RuntimeError("Unable to recognize platform")
|
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
def __build_from_github(dir: str, binary_name: str, github_url: str, build_cmd: str, compiled_relative_path: list[str], git_rev = None) -> BuildBinaryResult:
|
|
|
|
if git_rev is None:
|
2024-04-23 06:35:24 +00:00
|
|
|
versioned_binary_name = binary_name
|
2024-04-25 06:24:58 +00:00
|
|
|
elif binary_name.endswith(".exe"):
|
|
|
|
versioned_binary_name = binary_name.removesuffix(".exe") + f"_{git_rev}.exe"
|
|
|
|
else:
|
|
|
|
versioned_binary_name = f"{binary_name}_{git_rev}"
|
2024-04-23 06:35:24 +00:00
|
|
|
|
2024-04-19 12:24:50 +00:00
|
|
|
binary_path = os.path.join(dir, binary_name)
|
2024-04-23 06:35:24 +00:00
|
|
|
versioned_binary_path = os.path.join(dir, versioned_binary_name)
|
|
|
|
if os.path.exists(versioned_binary_path):
|
2024-04-25 03:25:05 +00:00
|
|
|
__create_sym_link(versioned_binary_name, binary_name, dir)
|
2024-04-25 06:24:58 +00:00
|
|
|
return BuildBinaryResult.AlreadyExists
|
2024-04-19 12:24:50 +00:00
|
|
|
|
|
|
|
start_time = time.time()
|
|
|
|
|
|
|
|
# clone code from github to a temp folder
|
|
|
|
code_tmp_dir_name = (binary_name[:-4] if is_windows_platform() else binary_name) + "_tmp"
|
|
|
|
code_tmp_dir = os.path.join(dir, code_tmp_dir_name)
|
|
|
|
if os.path.exists(code_tmp_dir):
|
|
|
|
shutil.rmtree(code_tmp_dir)
|
2024-04-23 06:35:24 +00:00
|
|
|
os.system(f"git clone {github_url} {code_tmp_dir}")
|
2024-04-19 12:24:50 +00:00
|
|
|
|
|
|
|
# build binary
|
|
|
|
origin_path = os.getcwd()
|
|
|
|
os.chdir(code_tmp_dir)
|
2024-04-23 06:35:24 +00:00
|
|
|
if git_rev is not None:
|
|
|
|
os.system(f"git checkout {git_rev}")
|
2024-04-19 12:24:50 +00:00
|
|
|
os.system(build_cmd)
|
|
|
|
|
|
|
|
# copy compiled binary to right place
|
|
|
|
compiled_binary = os.path.join(code_tmp_dir, *compiled_relative_path, binary_name)
|
2024-04-23 06:35:24 +00:00
|
|
|
shutil.copyfile(compiled_binary, versioned_binary_path)
|
2024-04-25 03:25:05 +00:00
|
|
|
__create_sym_link(versioned_binary_name, binary_name, dir)
|
2024-04-19 12:24:50 +00:00
|
|
|
|
|
|
|
if not is_windows_platform():
|
|
|
|
st = os.stat(binary_path)
|
|
|
|
os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
|
|
|
|
|
|
|
|
os.chdir(origin_path)
|
|
|
|
|
|
|
|
shutil.rmtree(code_tmp_dir, ignore_errors=True)
|
|
|
|
|
2024-04-23 06:35:24 +00:00
|
|
|
print("Completed to build binary " + binary_name + ", Elapsed: " + str(int(time.time() - start_time)) + " seconds", flush=True)
|
2024-04-19 12:24:50 +00:00
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
return BuildBinaryResult.Installed
|
2024-04-19 12:24:50 +00:00
|
|
|
|
2024-04-25 03:25:05 +00:00
|
|
|
def __create_sym_link(src, dst, path = None):
|
2024-04-23 06:35:24 +00:00
|
|
|
if src == dst:
|
|
|
|
return
|
|
|
|
|
|
|
|
origin_path = os.getcwd()
|
|
|
|
if path is not None:
|
|
|
|
os.chdir(path)
|
|
|
|
|
|
|
|
if os.path.exists(dst):
|
|
|
|
if os.path.isdir(dst):
|
|
|
|
shutil.rmtree(dst)
|
|
|
|
else:
|
|
|
|
os.remove(dst)
|
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
# Windows requires admin priviledge, use copy instead.
|
|
|
|
if is_windows_platform():
|
|
|
|
shutil.copy(src, dst)
|
|
|
|
else:
|
|
|
|
os.symlink(src, dst)
|
2024-04-23 06:35:24 +00:00
|
|
|
|
|
|
|
os.chdir(origin_path)
|
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
def __download_from_github(dir: str, binary_name: str, github_url: str, asset_name: str) -> BuildBinaryResult:
|
2024-04-19 12:24:50 +00:00
|
|
|
if not os.path.exists(dir):
|
|
|
|
os.makedirs(dir, exist_ok=True)
|
|
|
|
|
|
|
|
binary_path = os.path.join(dir, binary_name)
|
|
|
|
if os.path.exists(binary_path):
|
2024-04-25 06:24:58 +00:00
|
|
|
return BuildBinaryResult.AlreadyExists
|
2024-04-19 12:24:50 +00:00
|
|
|
|
|
|
|
print("Begin to download binary from github: %s" % binary_name, flush=True)
|
|
|
|
|
|
|
|
start_time = time.time()
|
|
|
|
|
2024-04-25 03:25:05 +00:00
|
|
|
req = requests.get(github_url)
|
|
|
|
assert req.ok, "Failed to request: %s" % github_url
|
|
|
|
download_url = None
|
|
|
|
for asset in req.json()["assets"]:
|
|
|
|
if asset["name"].lower() == asset_name:
|
|
|
|
download_url = asset["browser_download_url"]
|
|
|
|
break
|
2024-04-19 12:24:50 +00:00
|
|
|
|
2024-04-25 03:25:05 +00:00
|
|
|
if download_url is None:
|
|
|
|
print(f"Cannot find asset by name {asset_name}", flush=True)
|
2024-04-25 06:24:58 +00:00
|
|
|
return BuildBinaryResult.NotInstalled
|
2024-04-25 03:25:05 +00:00
|
|
|
|
|
|
|
content = requests.get(download_url).content
|
|
|
|
|
|
|
|
# Supports to read from zipped binary
|
|
|
|
if asset_name.endswith(".zip"):
|
|
|
|
asset_path = os.path.join(dir, asset_name)
|
|
|
|
with open(asset_path, "xb") as f:
|
|
|
|
f.write(content)
|
|
|
|
shutil.unpack_archive(asset_path, dir)
|
|
|
|
assert os.path.exists(binary_path), f"Cannot find binary after unzip, binary = {binary_name}, asset = {asset_name}"
|
|
|
|
else:
|
|
|
|
with open(binary_path, "xb") as f:
|
|
|
|
f.write(content)
|
2024-04-19 12:24:50 +00:00
|
|
|
|
2024-04-25 03:25:05 +00:00
|
|
|
if not is_windows_platform():
|
|
|
|
st = os.stat(binary_path)
|
|
|
|
os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
|
2024-04-19 12:24:50 +00:00
|
|
|
|
|
|
|
wait_until(lambda: os.access(binary_path, os.X_OK), timeout=120)
|
|
|
|
|
|
|
|
print("Completed to download binary, Elapsed: " + str(int(time.time() - start_time)) + " seconds", flush=True)
|
|
|
|
|
2024-04-25 06:24:58 +00:00
|
|
|
return BuildBinaryResult.Installed
|