install.sh: add --enterprise (#12660)

* install.sh: offer the vector engine on linux only

Releases build weed-vector for linux amd64/arm64 only, so --component vector
on darwin or windows downloaded a missing asset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK

* install.sh: add --enterprise

Installs from seaweedfs/artifactory: weed-enterprise-<os>_<arch>[_large_disk],
weed-volume-enterprise[_large_disk], weed-worker-enterprise and
weed-vector-enterprise. The latest tag skips vfs-* releases, and the Rust
volume server is linux-only there, so --component all skips it elsewhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK

* Revert "install.sh: offer the vector engine on linux only"

Releases after 4.53 publish weed-vector for darwin and windows too
(rust-vector-platforms.yml).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK

* install.sh: Enterprise vector engine is linux-only

Enterprise releases publish weed-vector-enterprise for linux amd64/arm64;
open-source releases keep their darwin and windows engines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK

* test: installer --enterprise asset names, platforms and latest tag

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK

* install.sh: Enterprise latest is the newest plain version tag

artifactory also releases previews and a dev build, and a prerelease such
as kvcache-filer-native-v0.1.0-preview.1 sits in the release list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK

* README: show passing --enterprise through bash -s --

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UpvafvK8JpagF94MHWqwK

* install.sh: the open-source weed for windows is a .zip too

Releases publish windows_amd64[_large_disk].zip, so asking for a .tar.gz
404s on every Windows host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* install.sh: install the windows weed as weed.exe

weed-volume and weed-vector keep their .exe on Windows; weed lost it, so
cmd and PowerShell could not run the installed binary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* install.sh: suggest weed-volume only when it was installed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chris LuandClaude Opus 5.5 authored and GitHub committed 2026-11-14 13:50:18 -08:00
1 parent b067266e6b
commit cdb01f8150
3 files changed
+125 -26

No files matched your search

+2
View File
@@ -67,6 +67,8 @@ Download the latest binary from the [releases](https://github.com/seaweedfs/seaw
curl -fsSL https://raw.githubusercontent.com/seaweedfs/seaweedfs/master/install.sh | bash
```
For SeaweedFS Enterprise binaries, pass `--enterprise` to the script: `... | bash -s -- --enterprise`.
Then start a ready-to-use S3 object store:
```bash
+65 -26
View File
@@ -7,12 +7,14 @@
# curl -fsSL https://raw.githubusercontent.com/seaweedfs/seaweedfs/master/install.sh | bash
# curl -fsSL ... | bash -s -- --component volume-rust --large-disk
# curl -fsSL ... | bash -s -- --version 4.34 --dir /usr/local/bin
# curl -fsSL ... | bash -s -- --enterprise --component all
#
# Options:
# --component COMP Which binary to install: weed, volume-rust, worker-rust, vector, all (default: weed)
# --version VER Release version tag (default: latest)
# --large-disk Use large disk variant (5-byte offset, 8TB max volume)
# --dir DIR Installation directory (default: /usr/local/bin)
# --enterprise Install SeaweedFS Enterprise binaries (from seaweedfs/artifactory)
# --help Show this help message
set -euo pipefail
@@ -24,6 +26,10 @@ LARGE_DISK=false
INSTALL_DIR="/usr/local/bin"
WORKER_INSTALLED=false
VECTOR_INSTALLED=false
VOLUME_INSTALLED=false
ENTERPRISE=false
# Enterprise assets carry this after the binary name, e.g. weed-vector-enterprise_linux_amd64.tar.gz.
EDITION=""
# Colors (if terminal supports them)
if [ -t 1 ]; then
@@ -53,6 +59,7 @@ while [ $# -gt 0 ]; do
--version) VERSION="$2"; shift 2 ;;
--large-disk) LARGE_DISK=true; shift ;;
--dir) INSTALL_DIR="$2"; shift 2 ;;
--enterprise) ENTERPRISE=true; REPO="seaweedfs/artifactory"; EDITION="-enterprise"; shift ;;
--help|-h) usage ;;
*) error "Unknown option: $1. Use --help for usage." ;;
esac
@@ -81,15 +88,22 @@ detect_platform() {
}
# Get latest release tag from GitHub API
# The Enterprise repo also releases other products (vfs-*, previews), which can
# be its latest release, so take the newest plain version tag like 4.53.
get_latest_version() {
local url="https://api.github.com/repos/${REPO}/releases/latest"
if [ "$ENTERPRISE" = true ]; then
url="https://api.github.com/repos/${REPO}/releases?per_page=30"
fi
local body
if command -v curl &>/dev/null; then
curl -fsSL "$url" | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/'
body="$(curl -fsSL "$url")"
elif command -v wget &>/dev/null; then
wget -qO- "$url" | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/'
body="$(wget -qO- "$url")"
else
error "Neither curl nor wget found. Please install one."
fi
echo "$body" | grep '"tag_name"' | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/' | grep -E '^[0-9]+(\.[0-9]+)+$' | head -1 || true
}
# Download a file
@@ -110,17 +124,22 @@ go_asset_name() {
if [ "$LARGE_DISK" = true ]; then
suffix="${suffix}_large_disk"
fi
echo "${suffix}.tar.gz"
if [ "$ENTERPRISE" = true ]; then
suffix="weed-enterprise-${suffix}"
fi
if [ "$os" = "windows" ]; then
echo "${suffix}.zip"
else
echo "${suffix}.tar.gz"
fi
}
# Build Rust volume server asset name
rust_asset_name() {
local os="$1" arch="$2"
local prefix="weed-volume"
local prefix="weed-volume${EDITION}"
if [ "$LARGE_DISK" = true ]; then
prefix="weed-volume_large_disk"
else
prefix="weed-volume"
prefix="${prefix}_large_disk"
fi
local suffix="${os}_${arch}"
if [ "$os" = "windows" ]; then
@@ -130,6 +149,19 @@ rust_asset_name() {
fi
}
# Enterprise publishes the Rust volume server for linux only.
rust_volume_platform_supported() {
case "$2" in
amd64|arm64) ;;
*) return 1 ;;
esac
case "$1" in
linux) return 0 ;;
darwin|windows) [ "$ENTERPRISE" != true ] ;;
*) return 1 ;;
esac
}
# Does a release carry this asset? Answers 0 for yes and 1 for a 404, and stops
# the installer on anything else: a rate limit or a network blip must not read
# as "this release predates the binary" and quietly skip it.
@@ -154,22 +186,23 @@ asset_exists() {
# maintains tables through the namespace and never opens a volume file.
worker_asset_name() {
local os="$1" arch="$2"
echo "weed-worker_${os}_${arch}.tar.gz"
echo "weed-worker${EDITION}_${os}_${arch}.tar.gz"
}
# The vector engine behind the S3 Vectors API, built like the worker.
vector_asset_name() {
local os="$1" arch="$2"
if [ "$os" = "windows" ]; then
echo "weed-vector_${os}_${arch}.zip"
echo "weed-vector${EDITION}_${os}_${arch}.zip"
else
echo "weed-vector_${os}_${arch}.tar.gz"
echo "weed-vector${EDITION}_${os}_${arch}.tar.gz"
fi
}
vector_platform_supported() {
case "$1/$2" in
linux/amd64|linux/arm64|darwin/amd64|darwin/arm64|windows/amd64) return 0 ;;
linux/amd64|linux/arm64) return 0 ;;
darwin/amd64|darwin/arm64|windows/amd64) [ "$ENTERPRISE" != true ] ;;
*) return 1 ;;
esac
}
@@ -189,7 +222,10 @@ install_component() {
download "$download_url" "${tmpdir}/${asset_name}"
info "Extracting ${asset_name}..."
tar xzf "${tmpdir}/${asset_name}" -C "$tmpdir"
case "$asset_name" in
*.zip) unzip -q "${tmpdir}/${asset_name}" -d "$tmpdir" ;;
*) tar xzf "${tmpdir}/${asset_name}" -C "$tmpdir" ;;
esac
# The Go release action puts the binary inside a directory
local weed_bin
@@ -202,20 +238,16 @@ install_component() {
fi
chmod +x "$weed_bin"
install_binary "$weed_bin" "weed"
ok "Installed weed to ${INSTALL_DIR}/weed"
local dest_name="weed"
if [ "$os" = "windows" ]; then
dest_name="weed.exe"
fi
install_binary "$weed_bin" "$dest_name"
ok "Installed weed to ${INSTALL_DIR}/${dest_name}"
;;
volume-rust)
# Check platform support for Rust volume server
case "$os" in
linux|darwin|windows) ;;
*) error "Rust volume server is not available for ${os}. Supported: linux, darwin, windows" ;;
esac
case "$arch" in
amd64|arm64) ;;
*) error "Rust volume server is not available for ${arch}. Supported: amd64, arm64" ;;
esac
rust_volume_platform_supported "$os" "$arch" || error "The Rust volume server is not available for ${os}/${arch}"
asset_name="$(rust_asset_name "$os" "$arch")"
download_url="https://github.com/${REPO}/releases/download/${VERSION}/${asset_name}"
@@ -247,6 +279,7 @@ install_component() {
dest_name="weed-volume.exe"
fi
install_binary "$rust_bin" "$dest_name"
VOLUME_INSTALLED=true
ok "Installed weed-volume to ${INSTALL_DIR}/${dest_name}"
;;
@@ -359,7 +392,11 @@ main() {
case "$COMPONENT" in
all)
install_component "weed" "$os" "$arch"
install_component "volume-rust" "$os" "$arch"
if rust_volume_platform_supported "$os" "$arch"; then
install_component "volume-rust" "$os" "$arch"
else
warn "Skipping the Rust volume server: no build for ${os}/${arch}"
fi
# The worker is published for linux amd64/arm64 only, and only by
# releases new enough to carry it; skip either case rather than fail
# an install that has already put two binaries in place.
@@ -388,7 +425,7 @@ main() {
if [ "$COMPONENT" = "weed" ] || [ "$COMPONENT" = "all" ]; then
info " weed: ${INSTALL_DIR}/weed"
fi
if [ "$COMPONENT" = "volume-rust" ] || [ "$COMPONENT" = "all" ]; then
if [ "$VOLUME_INSTALLED" = true ]; then
info " weed-volume: ${INSTALL_DIR}/weed-volume"
fi
if [ "$WORKER_INSTALLED" = true ]; then
@@ -401,7 +438,9 @@ main() {
info "Quick start:"
info " weed master # Start master server"
info " weed volume -mserver=localhost:9333 # Start Go volume server"
info " weed-volume -mserver localhost:9333 # Start Rust volume server"
if [ "$VOLUME_INSTALLED" = true ]; then
info " weed-volume -mserver localhost:9333 # Start Rust volume server"
fi
if [ "$WORKER_INSTALLED" = true ]; then
info " weed-worker --admin localhost:12535 # Start the Rust maintenance worker"
fi
+58
View File
@@ -57,3 +57,61 @@ class VectorInstallerTest(unittest.TestCase):
ARCHIVE=archive.as_posix(), DEST=dest.as_posix(), SYSTEM=system)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertEqual((dest / name).read_bytes(), contents)
class EnterpriseInstallerTest(unittest.TestCase):
shell = VectorInstallerTest.shell
def enterprise(self, code, **env):
return self.shell('ENTERPRISE=true; REPO=seaweedfs/artifactory; EDITION=-enterprise; ' + code, **env)
def test_asset_names(self):
result = self.enterprise('go_asset_name linux amd64; go_asset_name windows amd64; '
'rust_asset_name linux arm64; worker_asset_name linux amd64; '
'vector_asset_name linux arm64; LARGE_DISK=true; '
'go_asset_name darwin arm64; rust_asset_name linux amd64')
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.split(), [
'weed-enterprise-linux_amd64.tar.gz', 'weed-enterprise-windows_amd64.zip',
'weed-volume-enterprise_linux_arm64.tar.gz', 'weed-worker-enterprise_linux_amd64.tar.gz',
'weed-vector-enterprise_linux_arm64.tar.gz', 'weed-enterprise-darwin_arm64_large_disk.tar.gz',
'weed-volume-enterprise_large_disk_linux_amd64.tar.gz',
])
def test_open_source_go_asset_names(self):
result = self.shell('go_asset_name linux amd64; go_asset_name windows amd64; '
'LARGE_DISK=true; go_asset_name windows amd64')
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.split(), [
'linux_amd64.tar.gz', 'windows_amd64.zip', 'windows_amd64_large_disk.zip',
])
def test_windows_weed_keeps_exe(self):
with tempfile.TemporaryDirectory() as directory:
directory = Path(directory)
archive = directory / 'weed.zip'
with zipfile.ZipFile(archive, 'w') as output:
output.writestr('weed.exe', b'weed fixture')
dest = directory / 'bin'
result = self.shell('download() { cp "$ARCHIVE" "$2"; }; VERSION=test; '
'INSTALL_DIR="$DEST"; install_component weed windows amd64',
ARCHIVE=archive.as_posix(), DEST=dest.as_posix())
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertEqual((dest / 'weed.exe').read_bytes(), b'weed fixture')
def test_rust_binaries_linux_only(self):
for system, arch, supported in [
('linux', 'amd64', True), ('linux', 'arm64', True),
('darwin', 'arm64', False), ('windows', 'amd64', False),
]:
with self.subTest(system=system, arch=arch):
for check in ['vector_platform_supported', 'rust_volume_platform_supported']:
result = self.enterprise(f'{check} "$SYSTEM" "$ARCH"', SYSTEM=system, ARCH=arch)
self.assertEqual(result.returncode == 0, supported, check)
def test_latest_version_skips_other_releases(self):
tags = ['vfs-0.2.5', 'kvcache-filer-native-v0.1.0-preview.1', '4.54-rc1', '4.53', '4.52']
listing = ''.join(f' "tag_name": "{tag}",\\n' for tag in tags)
result = self.enterprise(f"curl() {{ printf '{listing}'; }}; get_latest_version")
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.strip(), '4.53')