diff --git a/Install-plotter.ps1 b/Install-plotter.ps1 new file mode 100644 index 0000000000..0cc237c351 --- /dev/null +++ b/Install-plotter.ps1 @@ -0,0 +1,195 @@ +<# +.DESCRIPTION + Install plotter binary +.PARAMETER v + The version of plotter to install +.EXAMPLES + PS> .\install-plotter.ps1 bladebit -v v2.0.0-beta1 + PS> .\install-plotter.ps1 madmax +#> +param( + [parameter(Position=0, Mandatory=$True, HelpMessage="'bladebit' or 'madmax'")] + [string]$plotter, + [parameter(HelpMessage="Specify the version of plotter to install")] + [string]$v +) + +$ErrorActionPreference = "Stop" + +if (("$plotter" -ne "bladebit") -And ("$plotter" -ne "madmax")) +{ + Write-Output "Plotter must be 'bladebit' or 'madmax'" + Exit 1 +} + +function get_bladebit_filename() +{ + param( + [string]$ver, + [string]$os, + [string]$arch + ) + + "bladebit-${ver}-${os}-${arch}.zip" +} + +function get_bladebit_url() +{ + param( + [string]$ver, + [string]$os, + [string]$arch + ) + + $GITHUB_BASE_URL = "https://github.com/Chia-Network/bladebit/releases/download" + $filename = get_bladebit_filename -ver $ver -os $os -arch $arch + + "${GITHUB_BASE_URL}/${ver}/${filename}" +} + +function get_madmax_filename() +{ + param( + [string]$ksize, + [string]$ver, + [string]$os, + [string]$arch + ) + + $chia_plot = "chia_plot" + if ("${ksize}" -eq "k34") + { + $chia_plot = "chia_plot_k34" + } + $suffix = "" + if ("${os}" -eq "macos") + { + $suffix = "-${os}-${arch}" + } + elseif("${os}" -eq "windows") + { + $suffix = ".exe" + } + else + { + $suffix = "-${arch}" + } + + "${chia_plot}-${ver}${suffix}" +} + +function get_madmax_url() +{ + param( + [string]$ksize, + [string]$ver, + [string]$os, + [string]$arch + ) + + $GITHUB_BASE_URL = "https://github.com/Chia-Network/chia-plotter-madmax/releases/download" + $madmax_filename = get_madmax_filename -ksize $ksize -ver $ver -os $os -arch $arch + + "${GITHUB_BASE_URL}/${ver}/${madmax_filename}" +} + +$DEFAULT_BLADEBIT_VERSION = "v2.0.0" +$DEFAULT_MADMAX_VERSION = "0.0.2" +$VERSION = $v +$OS = "windows" +$ARCH = "x86-64" + + +if ($null -eq (Get-ChildItem env:VIRTUAL_ENV -ErrorAction SilentlyContinue)) +{ + Write-Output "This script requires that the Chia Python virtual environment is activated." + Write-Output "Execute '.\venv\Scripts\Activate.ps1' before running." + Exit 1 +} + +$venv_bin = "${env:VIRTUAL_ENV}\Scripts" +if (-not (Test-Path -Path "$venv_bin" -PathType Container)) +{ + Write-Output "ERROR: venv folder does not exists: '${venv_bin}'" + Exit 1 +} + +Push-Location +try { + Set-Location "${venv_bin}" + $ErrorActionPreference = "SilentlyContinue" + + if ("${plotter}" -eq "bladebit") + { + if (-not($VERSION)) + { + $VERSION = $DEFAULT_BLADEBIT_VERSION + } + + Write-Output "Installing bladebit ${VERSION}" + + $URL = get_bladebit_url -ver "${VERSION}" -os "${OS}" -arch "${ARCH}" + Write-Output "Fetching binary from: ${URL}" + try { + Invoke-WebRequest -Uri "$URL" -OutFile ".\bladebit.zip" + Write-Output "Successfully downloaded: $URL" + } + catch { + Write-Output "ERROR: Download failed. Maybe specified version of the binary does not exist." + Pop-Location + Exit 1 + } + + Expand-Archive -Path ".\bladebit.zip" -DestinationPath ".\bladebit" + Move-Item .\bladebit\bladebit.exe .\ -Force + Remove-Item bladebit -Force + Remove-Item bladebit.zip -Force + Write-Output "Successfully installed bladebit to $(Get-Location)\bladebit.exe" + } + elseif("${plotter}" -eq "madmax") + { + if (-not($VERSION)) + { + $VERSION = $DEFAULT_MADMAX_VERSION + } + + Write-Output "Installing madmax ${VERSION}" + + $madmax_filename = get_madmax_filename -ksize k32 -ver "${VERSION}" -os "${OS}" -arch "${ARCH}" + $URL = get_madmax_url -ksize k32 -ver "${VERSION}" -os "${OS}" -arch "${ARCH}" + Write-Output "Fetching binary from: ${URL}" + try { + Invoke-WebRequest -Uri "$URL" -Outfile "chia_plot.exe" + Write-Output "Successfully downloaded: $URL" + Write-Output "Successfully installed madmax to $(Get-Location)\chia_plot.exe" + } + catch { + Write-Output "ERROR: Download failed. Maybe specified version of the binary does not exist." + Pop-Location + Exit 1 + } + + $madmax_filename = get_madmax_filename -ksize k34 -ver "${VERSION}" -os "${OS}" -arch "${ARCH}" + $URL = get_madmax_url -ksize k34 -ver "${VERSION}" -os "${OS}" -arch "${ARCH}" + Write-Output "Fetching binary from: ${URL}" + try { + Invoke-WebRequest -Uri "$URL" -Outfile "chia_plot_k34.exe" + Write-Output "Successfully downloaded: $URL" + Write-Output "Successfully installed madmax for k34 to $(Get-Location)\chia_plot_k34.exe" + } + catch { + Write-Output "madmax for k34 is not found" + } + } + else + { + Write-Output "Only 'bladebit' and 'madmax' are supported" + } +} +catch { + Write-Output "An error occurred:" + Write-Output $_ +} +finally { + Pop-Location +} diff --git a/Install.ps1 b/Install.ps1 index f561c9a0f8..d8efb28a87 100644 --- a/Install.ps1 +++ b/Install.ps1 @@ -1,6 +1,8 @@ param( [Parameter(HelpMessage="install development dependencies")] - [switch]$d = $False + [switch]$d = $False, + [Parameter()] + [switch]$p = $False ) $ErrorActionPreference = "Stop" @@ -106,6 +108,15 @@ venv\scripts\python -m pip install --upgrade pip setuptools wheel venv\scripts\pip install --extra-index-url https://pypi.chia.net/simple/ miniupnpc==2.2.2 venv\scripts\pip install --editable ".$extras_cli" --extra-index-url https://pypi.chia.net/simple/ +if ($p) +{ + $PREV_VIRTUAL_ENV = "$env:VIRTUAL_ENV" + $env:VIRTUAL_ENV = "venv" + .\Install-plotter.ps1 bladebit + .\Install-plotter.ps1 madmax + $env:VIRTUAL_ENV = "$PREV_VIRTUAL_ENV" +} + Write-Output "" Write-Output "Chia blockchain .\Install.ps1 complete." Write-Output "For assistance join us on Keybase in the #support chat channel:" diff --git a/chia/plotters/bladebit.py b/chia/plotters/bladebit.py index 7068b90fcb..0914723022 100644 --- a/chia/plotters/bladebit.py +++ b/chia/plotters/bladebit.py @@ -11,11 +11,8 @@ from chia.plotting.create_plots import resolve_plot_keys from chia.plotters.plotters_util import ( run_plotter, run_command, - check_git_repository, - check_git_ref, reset_loop_policy_for_windows, - get_linux_distro, - git_clean_checkout, + get_venv_bin, ) log = logging.getLogger(__name__) @@ -54,7 +51,7 @@ def meets_memory_requirement(plotters_root_path: Path) -> Tuple[bool, Optional[s return have_enough_memory, warning_string -def get_bladebit_install_path(plotters_root_path: Path) -> Path: +def get_bladebit_src_path(plotters_root_path: Path) -> Path: return plotters_root_path / BLADEBIT_PLOTTER_DIR @@ -62,11 +59,21 @@ def get_bladebit_package_path() -> Path: return Path(os.path.dirname(sys.executable)) / "bladebit" -def get_bladebit_exec_install_path(plotters_root_path: Path) -> Path: - bladebit_install_dir = get_bladebit_install_path(plotters_root_path) +def get_bladebit_exec_venv_path() -> Optional[Path]: + venv_bin_path = get_venv_bin() + if not venv_bin_path: + return None + if sys.platform in ["win32", "cygwin"]: + return venv_bin_path / "bladebit.exe" + else: + return venv_bin_path / "bladebit" + + +def get_bladebit_exec_src_path(plotters_root_path: Path) -> Path: + bladebit_src_dir = get_bladebit_src_path(plotters_root_path) build_dir = "build/Release" if sys.platform in ["win32", "cygwin"] else "build" bladebit_exec = "bladebit.exe" if sys.platform in ["win32", "cygwin"] else "bladebit" - return bladebit_install_dir / build_dir / bladebit_exec + return bladebit_src_dir / build_dir / bladebit_exec def get_bladebit_exec_package_path() -> Path: @@ -76,9 +83,12 @@ def get_bladebit_exec_package_path() -> Path: def get_bladebit_executable_path(plotters_root_path: Path) -> Path: - bladebit_exec_install_path = get_bladebit_exec_install_path(plotters_root_path) - if bladebit_exec_install_path.exists(): - return bladebit_exec_install_path + bladebit_exec_venv_path = get_bladebit_exec_venv_path() + if bladebit_exec_venv_path is not None and bladebit_exec_venv_path.exists(): + return bladebit_exec_venv_path + bladebit_exec_src_path = get_bladebit_exec_src_path(plotters_root_path) + if bladebit_exec_src_path.exists(): + return bladebit_exec_src_path return get_bladebit_exec_package_path() @@ -186,117 +196,6 @@ progress_bladebit2 = { } -def install_bladebit(root_path: Path, override: bool = False, commit: Optional[str] = None): - if not override and os.path.exists(get_bladebit_executable_path(root_path)): - print("Bladebit plotter already installed.") - print("You can override it with -o option") - return - - if not is_bladebit_supported(): - raise RuntimeError("Platform not supported yet for bladebit plotter.") - - if commit and not check_git_ref(commit): - raise RuntimeError("commit contains unusual string. Aborted.") - - print("Installing bladebit plotter.") - - if sys.platform in ["win32", "cygwin"]: - print("Windows user must build bladebit manually on \\plotters\\bladebit") - print("Please run `git clone` on the folder then build it as instructed in README") - raise RuntimeError("Automatic install not supported on Windows") - - if sys.platform.startswith("linux"): - distro = get_linux_distro() - if distro == "debian": - run_command( - [ - "sudo", - "apt", - "install", - "-y", - "build-essential", - "cmake", - "libnuma-dev", - "git", - "libgmp-dev", - ], - "Could not install dependencies", - ) - elif distro == "redhat": - run_command( - [ - "sudo", - "yum", - "groupinstall", - "-y", - "Development Tools", - ], - "Could not install Development Tools", - ) - run_command( - [ - "sudo", - "yum", - "install", - "-y", - "cmake", - "gcc-c++", - "gmp-devel", - "numactl-devel", - "git", - ], - "Could not install dependencies", - ) - else: - print("Unknown Linux distribution detected") - print("Tried to build with cmake anyway but it may require manual build if it fails") - elif sys.platform in ["darwin"]: - # 'brew' is a requirement for chia on macOS, so it should be available. - run_command(["brew", "install", "cmake"], "Could not install dependencies") - - bladebit_path: str = os.fspath(root_path.joinpath(BLADEBIT_PLOTTER_DIR)) - bladebit_git_origin_url = "https://github.com/Chia-Network/bladebit.git" - bladebit_git_repos_exist = check_git_repository(bladebit_path, bladebit_git_origin_url) - - if bladebit_git_repos_exist: - if commit: - git_clean_checkout(commit, bladebit_path) - elif override: - run_command(["git", "fetch", "origin"], "Failed to fetch origin", cwd=bladebit_path) - run_command( - ["git", "reset", "--hard", "origin/master"], "Failed to reset to origin/master", cwd=bladebit_path - ) - else: - # Rebuild with existing files - pass - else: - if commit: - run_command( - ["git", "clone", "--recursive", "--branch", commit, bladebit_git_origin_url], - "Could not clone bladebit repository", - cwd=os.fspath(root_path), - ) - else: - print("Cloning repository and its submodules.") - run_command( - ["git", "clone", "--recursive", bladebit_git_origin_url], - "Could not clone bladebit repository", - cwd=os.fspath(root_path), - ) - - build_path: str = os.fspath(Path(bladebit_path) / "build") - - print("Build bladebit.") - if not os.path.exists(build_path): - run_command(["mkdir", build_path], "Failed to create build directory", cwd=bladebit_path) - run_command(["cmake", ".."], "Failed to generate build config", cwd=build_path) - run_command( - ["cmake", "--build", ".", "--target", "bladebit", "--config", "Release"], - "Building bladebit failed", - cwd=build_path, - ) - - def plot_bladebit(args, chia_root_path, root_path): (found, version_or_exception) = get_bladebit_version(root_path) if found is None: @@ -325,24 +224,10 @@ def plot_bladebit(args, chia_root_path, root_path): print(f"Unknown version of bladebit: {args.plotter}") return - # When neither bladebit installed from git nor bladebit bundled with installer is available, - # install bladebit from git repos. - if not os.path.exists(get_bladebit_executable_path(root_path)): - print("Installing bladebit plotter.") - try: - # TODO: Change commit hash/branch name appropriately - if version == 1: - commit = "ad85a8f2cf99ca4c757932a21d937fdc9c7ae0ef" - elif version == 2: - commit = "develop" - else: - print(f"Unknown bladebit version {version}") - return - - install_bladebit(root_path, True, commit) - except Exception as e: - print(f"Exception while installing bladebit plotter: {e}") - return + bladebit_executable_path = get_bladebit_executable_path(root_path) + if not os.path.exists(bladebit_executable_path): + print("Bladebit was not found.") + return if sys.platform in ["win32", "cygwin"]: reset_loop_policy_for_windows() @@ -359,7 +244,7 @@ def plot_bladebit(args, chia_root_path, root_path): ) ) call_args = [ - os.fspath(get_bladebit_executable_path(root_path)), + os.fspath(bladebit_executable_path), "-t", str(args.threads), "-n", diff --git a/chia/plotters/madmax.py b/chia/plotters/madmax.py index 0eef77f7da..e88a605a3b 100644 --- a/chia/plotters/madmax.py +++ b/chia/plotters/madmax.py @@ -11,11 +11,7 @@ from chia.plotters.plotters_util import ( run_plotter, run_command, reset_loop_policy_for_windows, - get_linux_distro, - is_libsodium_available_on_redhat_like_os, - check_git_ref, - check_git_repository, - git_clean_checkout, + get_venv_bin, ) log = logging.getLogger(__name__) @@ -28,7 +24,7 @@ def is_madmax_supported() -> bool: return sys.platform.startswith("linux") or sys.platform in ["darwin", "win32", "cygwin"] -def get_madmax_install_path(plotters_root_path: Path) -> Path: +def get_madmax_src_path(plotters_root_path: Path) -> Path: return plotters_root_path / MADMAX_PLOTTER_DIR @@ -36,14 +32,26 @@ def get_madmax_package_path() -> Path: return Path(os.path.dirname(sys.executable)) / "madmax" -def get_madmax_exec_install_path(plotters_root_path: Path, ksize: int = 32) -> Path: - madmax_install_dir = get_madmax_install_path(plotters_root_path) / "build" +def get_madmax_exec_venv_path(ksize: int = 32) -> Optional[Path]: + venv_bin_path = get_venv_bin() + if not venv_bin_path: + return None madmax_exec = "chia_plot" if ksize > 32: madmax_exec += "_k34" # Use the chia_plot_k34 executable for k-sizes > 32 if sys.platform in ["win32", "cygwin"]: madmax_exec += ".exe" - return madmax_install_dir / madmax_exec + return venv_bin_path / madmax_exec + + +def get_madmax_exec_src_path(plotters_root_path: Path, ksize: int = 32) -> Path: + madmax_src_dir = get_madmax_src_path(plotters_root_path) / "build" + madmax_exec = "chia_plot" + if ksize > 32: + madmax_exec += "_k34" # Use the chia_plot_k34 executable for k-sizes > 32 + if sys.platform in ["win32", "cygwin"]: + madmax_exec += ".exe" + return madmax_src_dir / madmax_exec def get_madmax_exec_package_path(ksize: int = 32) -> Path: @@ -57,9 +65,12 @@ def get_madmax_exec_package_path(ksize: int = 32) -> Path: def get_madmax_executable_path_for_ksize(plotters_root_path: Path, ksize: int = 32) -> Path: - madmax_exec_install_path = get_madmax_exec_install_path(plotters_root_path, ksize) - if madmax_exec_install_path.exists(): - return madmax_exec_install_path + madmax_exec_venv_path = get_madmax_exec_venv_path(ksize) + if madmax_exec_venv_path is not None and madmax_exec_venv_path.exists(): + return madmax_exec_venv_path + madmax_exec_src_path = get_madmax_exec_src_path(plotters_root_path, ksize) + if madmax_exec_src_path.exists(): + return madmax_exec_src_path return get_madmax_exec_package_path(ksize) @@ -112,158 +123,6 @@ def get_madmax_install_info(plotters_root_path: Path) -> Optional[Dict[str, Any] return info -def install_madmax(plotters_root_path: Path, override: bool = False, commit: Optional[str] = None): - if not override and os.path.exists(get_madmax_executable_path_for_ksize(plotters_root_path)): - print("Madmax plotter already installed.") - print("You can override it with -o option") - return - - if not is_madmax_supported(): - raise RuntimeError("Platform not supported yet for madmax plotter.") - - if commit and not check_git_ref(commit): - raise RuntimeError("commit contains unusual string. Aborted.") - - print("Installing madmax plotter.") - - if sys.platform in ["win32", "cygwin"]: - print("Automatic install not supported on Windows") - print("GUI and 'chia plotters madmax' command recognize madmax exec installed at:") - print(f" {get_madmax_exec_install_path(plotters_root_path)}") - print("If you have Windows madmax binary, put that binary to the directory above") - raise RuntimeError("Automatic install not supported on Windows") - - print("Installing dependencies.") - if sys.platform.startswith("linux"): - distro = get_linux_distro() - if distro == "debian": - run_command( - [ - "sudo", - "apt", - "update", - "-y", - ], - "Could not update get package information from apt", - ) - run_command( - [ - "sudo", - "apt", - "install", - "-y", - "libsodium-dev", - "cmake", - "g++", - "git", - "build-essential", - ], - "Could not install dependencies", - ) - elif distro == "redhat": - if not is_libsodium_available_on_redhat_like_os(): - print("libsodium-devel is required but not available") - return - - run_command( - [ - "sudo", - "yum", - "groupinstall", - "-y", - "Development Tools", - ], - "Could not install Development Tools", - ) - run_command( - [ - "sudo", - "yum", - "install", - "-y", - "cmake", - "gcc-c++", - "git", - ], - "Could not install dependencies", - ) - if sys.platform.startswith("darwin"): - run_command( - [ - "brew", - "install", - "libsodium", - "cmake", - "git", - "autoconf", - "automake", - "libtool", - "wget", - ], - "Could not install dependencies", - ) - - madmax_path: str = os.fspath(plotters_root_path.joinpath(MADMAX_PLOTTER_DIR)) - madmax_git_origin_url = "https://github.com/Chia-Network/chia-plotter-madmax.git" - madmax_git_repos_exist = check_git_repository(madmax_path, madmax_git_origin_url) - - if madmax_git_repos_exist: - print("Checking out git repository") - if commit: - git_clean_checkout(commit, madmax_path) - elif override: - run_command(["git", "fetch", "origin"], "Failed to fetch origin", cwd=madmax_path) - run_command( - ["git", "reset", "--hard", "origin/master"], "Failed to reset to origin/master", cwd=madmax_path - ) - else: - # Rebuild with existing files - pass - else: - print("Cloning git repository.") - if commit: - run_command( - [ - "git", - "clone", - "--branch", - commit, - madmax_git_origin_url, - MADMAX_PLOTTER_DIR, - ], - "Could not clone madmax repository", - cwd=os.fspath(plotters_root_path), - ) - else: - run_command( - [ - "git", - "clone", - madmax_git_origin_url, - MADMAX_PLOTTER_DIR, - ], - "Could not clone madmax repository", - cwd=os.fspath(plotters_root_path), - ) - - madmax_path = os.fspath(get_madmax_install_path(plotters_root_path)) - print("Installing git submodules.") - run_command( - [ - "git", - "submodule", - "update", - "--init", - "--recursive", - ], - "Could not initialize git submodules", - cwd=madmax_path, - ) - - print("Running install script.") - run_command(["./make_devel.sh"], "Error while running install script", cwd=madmax_path) - - progress = { "[P1] Table 1 took": 0.01, "[P1] Table 2 took": 0.06, @@ -301,13 +160,11 @@ def plot_madmax(args, chia_root_path: Path, plotters_root_path: Path): else: reset_loop_policy_for_windows() - if not os.path.exists(get_madmax_executable_path_for_ksize(plotters_root_path, args.size)): - print("Installing madmax plotter.") - try: - install_madmax(plotters_root_path) - except Exception as e: - print(f"Exception while installing madmax plotter: {e}") - return + madmax_executable_path_for_ksize = get_madmax_executable_path_for_ksize(plotters_root_path, args.size) + if not os.path.exists(madmax_executable_path_for_ksize): + print("madmax plotter was not found.") + return + plot_keys = asyncio.run( resolve_plot_keys( None if args.farmerkey == b"" else args.farmerkey.hex(), @@ -320,7 +177,7 @@ def plot_madmax(args, chia_root_path: Path, plotters_root_path: Path): ) ) call_args = [] - call_args.append(os.fspath(get_madmax_executable_path_for_ksize(plotters_root_path, args.size))) + call_args.append(os.fspath(madmax_executable_path_for_ksize)) call_args.append("-f") call_args.append(bytes(plot_keys.farmer_public_key).hex()) if plot_keys.pool_public_key is not None: diff --git a/chia/plotters/plotters.py b/chia/plotters/plotters.py index e3e4f06fea..31ea7add20 100644 --- a/chia/plotters/plotters.py +++ b/chia/plotters/plotters.py @@ -2,13 +2,9 @@ import argparse import binascii import os from enum import Enum -from chia.plotters.bladebit import ( - get_bladebit_install_info, - plot_bladebit, - install_bladebit, -) +from chia.plotters.bladebit import get_bladebit_install_info, plot_bladebit from chia.plotters.chiapos import get_chiapos_install_info, plot_chia -from chia.plotters.madmax import get_madmax_install_info, plot_madmax, install_madmax +from chia.plotters.madmax import get_madmax_install_info, plot_madmax from pathlib import Path from typing import Any, Dict, Optional @@ -418,57 +414,6 @@ def build_parser(subparsers, root_path, option_list, name, plotter_desc): ) -def install_plotter(args: argparse.Namespace, root_path: Path): - plotter = args.install_plotter - override = args.override - commit = args.commit - - if plotter == "chiapos": - print("Chiapos already installed. No action taken.") - return - elif plotter == "madmax": - try: - install_madmax(root_path, override, commit) - except Exception as e: - print(f"Exception while installing madmax plotter: {e}") - return - elif plotter == "bladebit": - try: - install_bladebit(root_path, override, commit or "ad85a8f2cf99ca4c757932a21d937fdc9c7ae0ef") - except Exception as e: - print(f"Exception while installing bladebit plotter: {e}") - return - elif plotter == "bladebit2": - try: - install_bladebit(root_path, override, commit or "develop") - except Exception as e: - print(f"Exception while installing bladebit plotter: {e}") - return - else: - print("Unknown plotter. No action taken.") - return - - -def build_install_parser(subparsers): - subparsers.add_argument( - "install_plotter", type=str, help="The plotters available for installing. Choose from madmax or bladebit." - ) - subparsers.add_argument( - "-o", - "--override", - action="store_true", - help="Override existing install", - default=False, - ) - subparsers.add_argument( - "-c", - "--commit", - type=str, - help="Git branch/tag/hash of plotter's git repository", - default=None, - ) - - def call_plotters(root_path: Path, args): # Add `plotters` section in CHIA_ROOT. chia_root_path = root_path @@ -495,22 +440,26 @@ def call_plotters(root_path: Path, args): build_parser(subparsers, root_path, bladebit_plotter_options, "bladebit", "Bladebit Plotter") build_parser(subparsers, root_path, bladebit2_plotter_options, "bladebit2", "Bladebit2 Plotter") - install_parser = subparsers.add_parser("install", description="Install custom plotters.") - build_install_parser(install_parser) + deprecation_warning = ( + "[DEPRECATED] 'chia plotters install' is no longer available. Use install-plotter.sh/ps1 instead." + ) + install_parser = subparsers.add_parser("install", description=deprecation_warning) + install_parser.add_argument("install_plotter", type=str, nargs="*") + subparsers.add_parser("version", description="Show plotter versions") args = plotters.parse_args(args) if args.plotter == "chiapos": plot_chia(args, chia_root_path) - if args.plotter == "madmax": + elif args.plotter == "madmax": plot_madmax(args, chia_root_path, root_path) - if args.plotter.startswith("bladebit"): + elif args.plotter.startswith("bladebit"): plot_bladebit(args, chia_root_path, root_path) - if args.plotter == "install": - install_plotter(args, root_path) - if args.plotter == "version": + elif args.plotter == "version": show_plotters_version(chia_root_path) + elif args.plotter == "install": + print(deprecation_warning) def get_available_plotters(root_path) -> Dict[str, Any]: diff --git a/chia/plotters/plotters_util.py b/chia/plotters/plotters_util.py index cdd9da4324..fc12fd294f 100644 --- a/chia/plotters/plotters_util.py +++ b/chia/plotters/plotters_util.py @@ -3,7 +3,7 @@ from __future__ import annotations import asyncio import contextlib import json -import re +import os import signal import subprocess import sys @@ -110,65 +110,18 @@ def run_command(args, exc_description, *, check=True, **kwargs) -> subprocess.Co return proc -def check_git_repository(git_dir: str, expected_origin_url: str): - command = ["git", "remote", "get-url", "origin"] - try: - proc = subprocess.run(command, capture_output=True, check=True, text=True, cwd=git_dir) - return proc.stdout.strip() == expected_origin_url - except Exception as e: - print(f"Error while executing \"{' '.join(command)}\"") - print(e) - return False - - -# If raw value of `git_ref` is passed to command string `git reset --hard {git_ref}` without any check, -# it would be a security risk. This check will eliminate unusual ref string before it is used. -# See https://git-scm.com/docs/git-check-ref-format (This check is stricter than the specification) -def check_git_ref(git_ref: str): - if len(git_ref) > 50: - return False - - test = ( - re.match(r"[^\w.@/-]", git_ref) - or re.match(r"\.\.", git_ref) - or re.match(r"\.$", git_ref) - or re.match(r"@\{", git_ref) - or re.match(r"^@$", git_ref) - ) - - return False if test else True - - def reset_loop_policy_for_windows(): asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) -def get_linux_distro(): - result = subprocess.run(["sh", "-c", "type apt"]) - if result.returncode == 0: - return "debian" - result = subprocess.run(["sh", "-c", "type yum"]) - if result.returncode == 0: - return "redhat" - return "unknown" +def get_venv_bin(): + venv_dir = os.environ.get("VIRTUAL_ENV", None) + if not venv_dir: + return None + venv_path = Path(venv_dir) -def is_libsodium_available_on_redhat_like_os(): - result = subprocess.run(["ls", "/usr/include/sodium.h"]) - if result.returncode == 0: - return True - result = subprocess.run(["sudo", "yum", "info", "libsodium-devel"]) - if result.returncode != 0: - return False - result = subprocess.run(["sudo", "yum", "install", "-y", "libsodium-devel"]) - return result.returncode == 0 - - -def git_clean_checkout(commit: str, plotter_dir: str): - run_command(["git", "reset", "--hard"], "Failed to reset head", cwd=plotter_dir) - run_command(["git", "clean", "-fd"], "Failed to clean working tree", cwd=plotter_dir) - now = datetime.now().strftime("%Y%m%d%H%M%S") - run_command(["git", "branch", "-m", now], f"Failed to rename branch to {now}", cwd=plotter_dir) - run_command(["git", "fetch", "origin", "--prune"], "Failed to fetch remote branches ", cwd=plotter_dir) - run_command(["git", "checkout", "-f", commit], f"Failed to checkout {commit}", cwd=plotter_dir) - run_command(["git", "branch", "-D", now], f"Failed to delete branch {now}", cwd=plotter_dir) + if sys.platform == "win32": + return venv_path / "Scripts" + else: + return venv_path / "bin" diff --git a/install-plotter.sh b/install-plotter.sh new file mode 100755 index 0000000000..2189c15c08 --- /dev/null +++ b/install-plotter.sh @@ -0,0 +1,198 @@ +#!/bin/bash + +set -o errexit + +USAGE_TEXT="\ +Usage: $0 [-v VERSION | -h] + + -v VERSION Specify the version of plotter to install + -h Show usage +" + +usage() { + echo "${USAGE_TEXT}" +} + +get_bladebit_filename() { + BLADEBIT_VER="$1" # e.g. v2.0.0-beta1 + OS="$2" # "ubuntu", "centos", "macos" + ARCH="$3" # "x86-64", "arm64" + + echo "bladebit-${BLADEBIT_VER}-${OS}-${ARCH}.tar.gz" +} + +get_bladebit_url() { + BLADEBIT_VER="$1" # e.g. v2.0.0-beta1 + OS="$2" # "ubuntu", "centos", "macos" + ARCH="$3" # "x86-64", "arm64" + + GITHUB_BASE_URL="https://github.com/Chia-Network/bladebit/releases/download" + BLADEBIT_FILENAME="$(get_bladebit_filename "${BLADEBIT_VER}" "${OS}" "${ARCH}")" + + echo "${GITHUB_BASE_URL}/${BLADEBIT_VER}/${BLADEBIT_FILENAME}" +} + +get_madmax_filename() { + KSIZE="$1" # "k34" or other + MADMAX_VER="$2" # e.g. 0.0.2 + OS="$3" # "macos", others + ARCH="$4" # "arm64", "x86-64" + + CHIA_PLOT="chia_plot" + if [ "$KSIZE" = "k34" ]; then + CHIA_PLOT="chia_plot_k34" + fi + SUFFIX="" + if [ "$OS" = "macos" ]; then + if [ "$ARCH" = "arm64" ]; then + ARCH="m1" + else + ARCH="intel" + fi + SUFFIX="${OS}-${ARCH}" + else + SUFFIX="${ARCH}" + fi + + echo "${CHIA_PLOT}-${MADMAX_VER}-${SUFFIX}" +} + +get_madmax_url() { + KSIZE="$1" # "k34" or other + MADMAX_VER="$2" # e.g. 0.0.2 + OS="$3" # "macos", others + ARCH="$4" # "intel", "m1", "arm64", "x86-64" + + GITHUB_BASE_URL="https://github.com/Chia-Network/chia-plotter-madmax/releases/download" + MADMAX_FILENAME="$(get_madmax_filename "${KSIZE}" "${MADMAX_VER}" "${OS}" "${ARCH}")" + + echo "${GITHUB_BASE_URL}/${MADMAX_VER}/${MADMAX_FILENAME}" +} + + +if [ "$1" = "-h" ] || [ -z "$1" ]; then + usage + exit 0 +fi + +DEFAULT_BLADEBIT_VERSION="v2.0.0" +DEFAULT_MADMAX_VERSION="0.0.2" +VERSION= +PLOTTER=$1 +shift 1 + +while getopts v:h flag +do + case "${flag}" in + # version + v) VERSION="$OPTARG";; + h) usage; exit 0;; + *) echo; usage; exit 1;; + esac +done + +SCRIPT_DIR=$(cd -- "$(dirname -- "$0")"; pwd) + +if [ "${SCRIPT_DIR}" != "$(pwd)" ]; then + echo "ERROR: Please change working directory by the command below" + echo " cd ${SCRIPT_DIR}" + exit 1 +fi + +if [ -z "$VIRTUAL_ENV" ]; then + echo "This requires the chia python virtual environment." + echo "Execute '. ./activate' before running." + exit 1 +fi + +if [ "$(id -u)" = 0 ]; then + echo "ERROR: Plotter can not be installed or run by the root user." + exit 1 +fi + +OS="" +ARCH="x86-64" +if [ "$(uname)" = "Linux" ]; then + # Debian / Ubuntu + if command -v apt-get >/dev/null; then + echo "Detected Debian/Ubuntu like OS" + OS="ubuntu" + # RedHut / CentOS / Rocky / AMLinux + elif type yum >/dev/null 2>&1; then + echo "Detected RedHut like OS" + OS="centos" + else + echo "ERROR: Unknown Linux distro" + exit 1 + fi +# MacOS +elif [ "$(uname)" = "Darwin" ]; then + echo "Detected MacOS" + OS="macos" +else + echo "ERROR: $(uname) is not supported" + exit 1 +fi + +if [ "$(uname -m)" = "aarch64" ] || [ "$(uname -m)" = "arm64" ]; then + ARCH="arm64" +fi + +if [ ! -d "${VIRTUAL_ENV}/bin" ]; then + echo "ERROR: venv directory does not exists: '${VIRTUAL_ENV}/bin'" + exit 1 +fi +cd "${VIRTUAL_ENV}/bin" + +if [ "$PLOTTER" = "bladebit" ]; then + if [ -z "$VERSION" ]; then + VERSION="$DEFAULT_BLADEBIT_VERSION" + fi + + echo "Installing bladebit $VERSION" + + URL="$(get_bladebit_url "${VERSION}" "${OS}" "${ARCH}")" + echo "Fetching binary from: ${URL}" + if ! wget -q "${URL}"; then + echo "ERROR: Download failed. Maybe specified version of the binary does not exist." + exit 1 + fi + echo "Successfully downloaded: ${URL}" + bladebit_filename="$(get_bladebit_filename "${VERSION}" "${OS}" "${ARCH}")" + tar zxf "${bladebit_filename}" + chmod 755 ./bladebit + rm -f "${bladebit_filename}" + echo "Successfully installed bladebit to $(pwd)/bladebit" +elif [ "$PLOTTER" = "madmax" ]; then + if [ -z "$VERSION" ]; then + VERSION="$DEFAULT_MADMAX_VERSION" + fi + + echo "Installing madmax $VERSION" + + URL="$(get_madmax_url k32 "${VERSION}" "${OS}" "${ARCH}")" + echo "Fetching binary from: ${URL}" + if ! wget -q "${URL}"; then + echo "ERROR: Download failed. Maybe specified version of the binary does not exist." + exit 1 + fi + echo "Successfully downloaded: ${URL}" + madmax_filename="$(get_madmax_filename "k32" "${VERSION}" "${OS}" "${ARCH}")" + mv -f "${madmax_filename}" chia_plot + chmod 755 chia_plot + echo "Successfully installed madmax to $(pwd)/chia_plot" + + URL="$(get_madmax_url k34 "${VERSION}" "${OS}" "${ARCH}")" + echo "Fetching binary from: ${URL}" + if ! wget -q "${URL}"; then + echo "madmax for k34 for this version is not found" + exit 1 + fi + echo "Successfully downloaded: ${URL}" + madmax_filename="$(get_madmax_filename "k34" "${VERSION}" "${OS}" "${ARCH}")" + mv -f "${madmax_filename}" chia_plot_k34 + chmod 755 chia_plot_k34 + echo "Successfully installed madmax for k34 to $(pwd)/chia_plot_k34" +else + usage +fi diff --git a/install.sh b/install.sh index d1f701026a..4c1909d51f 100755 --- a/install.sh +++ b/install.sh @@ -3,11 +3,12 @@ set -o errexit USAGE_TEXT="\ -Usage: $0 [-adsh] +Usage: $0 [-adsph] -a automated install, no questions -d install development dependencies -s skip python package installation and just do pip install + -p additional plotters installation -h display this help and exit " @@ -18,8 +19,9 @@ usage() { PACMAN_AUTOMATED= EXTRAS= SKIP_PACKAGE_INSTALL= +PLOTTER_INSTALL= -while getopts adsh flag +while getopts adsph flag do case "${flag}" in # automated @@ -28,6 +30,7 @@ do d) EXTRAS=${EXTRAS}dev,;; # simple install s) SKIP_PACKAGE_INSTALL=1;; + p) PLOTTER_INSTALL=1;; h) usage; exit 0;; *) echo; usage; exit 1;; esac @@ -338,6 +341,16 @@ python -m pip install wheel python -m pip install --extra-index-url https://pypi.chia.net/simple/ miniupnpc==2.2.2 python -m pip install -e ."${EXTRAS}" --extra-index-url https://pypi.chia.net/simple/ +if [ -n "$PLOTTER_INSTALL" ]; then + set +e + PREV_VENV="$VIRTUAL_ENV" + export VIRTUAL_ENV="venv" + ./install-plotter.sh bladebit + ./install-plotter.sh madmax + export VIRTUAL_ENV="$PREV_VENV" + set -e +fi + echo "" echo "Chia blockchain install.sh complete." echo "For assistance join us on Keybase in the #support chat channel:"