-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SM-1130] - add install scripts #645
Merged
+313
−4
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
b39cc93
add install scripts
tangowithfoxtrot 9d72a15
Merge branch 'main' into sm/SM-1130/host-a-generic-install-script
tangowithfoxtrot 25464c8
fix arm arch and fmt error
tangowithfoxtrot 51f1fc8
allow overriding bws version; use Bitwarden for path name
tangowithfoxtrot c798283
update to 0.5.0
tangowithfoxtrot 276beef
fix erroneous newline
tangowithfoxtrot 1e4a441
add checksum validation
tangowithfoxtrot 3160a61
Merge branch 'main' into sm/SM-1130/host-a-generic-install-script
tangowithfoxtrot 83f53d3
rm todo; grammar
tangowithfoxtrot f16cf6d
fix macOS arch check; quote vars
tangowithfoxtrot 34e840e
fix macOS arm arch; quote vars
tangowithfoxtrot a3ff347
Merge branch 'sm/SM-1130/host-a-generic-install-script' of https://gi…
tangowithfoxtrot c236af2
use PS-friendly names
tangowithfoxtrot 4aa9bc2
add version bumps for install scripts
tangowithfoxtrot c0e67ba
Merge branch 'main' into sm/SM-1130/host-a-generic-install-script
tangowithfoxtrot b6e0b3f
fix: match correct checksum for arch
tangowithfoxtrot 0dd2fda
fix: checksum validation for macs without coreutils
tangowithfoxtrot 0c3b568
move to scripts dir
tangowithfoxtrot 24e0e98
add uninstallation arg
tangowithfoxtrot 2dba059
use easier regex matching
tangowithfoxtrot 035ca93
mention install script in docs
tangowithfoxtrot 3ff5cde
Merge branch 'main' into sm/SM-1130/host-a-generic-install-script
tangowithfoxtrot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
param ( | ||
[switch]$Uninstall | ||
) | ||
|
||
$ErrorActionPreference = "Stop" | ||
|
||
$defaultBwsVersion = "0.5.0" | ||
$bwsVersion = if ($env:bwsVersion) { $env:bwsVersion } else { $defaultBwsVersion } | ||
$installDir = [Environment]::GetFolderPath([Environment+SpecialFolder]::LocalApplicationData) | Join-Path -ChildPath "Programs" | Join-Path -ChildPath "Bitwarden" | ||
|
||
# https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor#properties | ||
$processorArch = (Get-CimInstance -ClassName Win32_Processor).Architecture | ||
if ($processorArch -eq 9) { | ||
$arch = "x86_64" | ||
} elseif ($processorArch -eq 12) { | ||
$arch = "aarch64" | ||
} else { | ||
throw "Unsupported architecture: $processorArch" | ||
} | ||
|
||
function Test-BwsInstallation { | ||
$existingBws = Get-Command bws -ErrorAction SilentlyContinue | ||
if ($null -ne $existingBws) { | ||
$userInput = Read-Host "bws is already installed at $($existingBws.Source). Do you want to overwrite it? (Y/N)" | ||
if ($userInput -ne "Y") { | ||
Write-Host "Installation cancelled by user." | ||
exit | ||
} | ||
} | ||
} | ||
|
||
function Invoke-BwsDownload { | ||
Write-Host "Detected architecture: $arch" | ||
|
||
$bwsUrl = "https://github.com/bitwarden/sdk/releases/download/bws-v$bwsVersion/bws-$arch-pc-windows-msvc-$bwsVersion.zip" | ||
Write-Host "Downloading bws from: $bwsUrl" | ||
$outputPath = Join-Path $env:TEMP "bws.zip" | ||
Invoke-WebRequest -Uri $bwsUrl -OutFile $outputPath | ||
return $outputPath | ||
} | ||
|
||
function Test-Checksum { | ||
param($zipPath) | ||
Write-Host "Validating checksum..." | ||
|
||
$checksumUrl = "https://github.com/bitwarden/sdk/releases/download/bws-v$bwsVersion/bws-sha256-checksums-$bwsVersion.txt" | ||
$checksumFile = Join-Path $env:TEMP "bws-checksums.txt" | ||
Invoke-WebRequest -Uri $checksumUrl -OutFile $checksumFile | ||
|
||
$expectedChecksum = (Get-Content $checksumFile | Where-Object { $_ -match "bws-$arch-pc-windows-msvc-$bwsVersion.zip" }).Split(" ")[0] | ||
$actualChecksum = (Get-FileHash -Algorithm SHA256 -Path $zipPath).Hash | ||
|
||
if ($actualChecksum -ne $expectedChecksum) { | ||
throw "Checksum validation failed. Expected: $expectedChecksum, Actual: $actualChecksum" | ||
} else { | ||
Write-Host "Checksum validation successful." | ||
} | ||
} | ||
|
||
function Install-Bws { | ||
param($zipPath) | ||
Write-Host "Installing bws..." | ||
New-Item -ItemType Directory -Force -Path $installDir | Out-Null | ||
Expand-Archive -Force $zipPath -DestinationPath $installDir | ||
Write-Host "bws installed to $installDir" | ||
setx PATH "$env:PATH;$installDir" | ||
Write-Host "$installDir has been added to your PATH" | ||
Write-Host "Please restart your shell to use bws" | ||
} | ||
|
||
function Test-Bws { | ||
Write-Host "Checking bws..." | ||
$bwsPath = Join-Path $installDir "bws.exe" | ||
if (Test-Path $bwsPath) { | ||
Write-Host "bws is installed at $bwsPath" | ||
} else { | ||
throw "bws is not installed" | ||
} | ||
} | ||
|
||
function Remove-Bws { | ||
Write-Host "Uninstalling bws..." | ||
|
||
if (Test-Path $installDir) { | ||
Remove-Item -Path $installDir -Recurse -Force | ||
Write-Host "bws uninstalled from $installDir" | ||
} else { | ||
Write-Host "bws installation directory not found at $installDir. Skipping removal." | ||
} | ||
|
||
$configDir = "$env:USERPROFILE\.bws" | ||
if (Test-Path $configDir -PathType Container) { | ||
Remove-Item -Path $configDir -Recurse -Force | ||
Write-Host "bws config directory removed from $configDir" | ||
} else { | ||
Write-Host "bws config directory not found at $configDir. Skipping removal." | ||
} | ||
} | ||
|
||
if ($Uninstall) { | ||
Remove-Bws | ||
} else { | ||
Test-BwsInstallation | ||
$zipPath = Invoke-BwsDownload | ||
Test-Checksum -zipPath $zipPath | ||
Install-Bws -zipPath $zipPath | ||
Test-Bws | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
#!/bin/sh | ||
|
||
################################################## | ||
# An installer for the bws command line utility. # | ||
################################################## | ||
|
||
DEFAULT_BWS_VERSION="0.5.0" | ||
BWS_VERSION="${BWS_VERSION:-$DEFAULT_BWS_VERSION}" | ||
|
||
main() { | ||
case "$1" in | ||
-u | --uninstall) | ||
uninstall_bws | ||
;; | ||
*) | ||
check_required | ||
platform_detect | ||
arch_detect | ||
download_bws | ||
validate_checksum | ||
install_bws | ||
;; | ||
esac | ||
} | ||
|
||
error() { | ||
echo "$1" >&2 | ||
echo "Exiting..." >&2 | ||
exit 1 | ||
} | ||
|
||
check_required() { | ||
if ! command -v curl >/dev/null && ! command -v wget >/dev/null; then | ||
error "curl or wget is required to download bws." | ||
fi | ||
|
||
if ! command -v unzip >/dev/null; then | ||
error "unzip is required to install bws." | ||
fi | ||
} | ||
|
||
can_sudo() { | ||
if command -v sudo >/dev/null; then | ||
echo "Attempting to install bws with sudo. Please enter your password if prompted." | ||
if sudo -v 2>/dev/null; then | ||
echo "sudo is available and we have the necessary permissions." | ||
echo "Installing bws to /usr/local/bin..." | ||
return 0 | ||
else | ||
echo "sudo is available, but we failed to authenticate." | ||
return 1 | ||
fi | ||
else | ||
echo "sudo is not available." | ||
return 1 | ||
fi | ||
} | ||
|
||
platform_detect() { | ||
if [ "$(uname -s)" = "Linux" ]; then | ||
PLATFORM="unknown-linux-gnu" | ||
elif [ "$(uname -s)" = "Darwin" ]; then | ||
PLATFORM="apple-darwin" | ||
else | ||
error "Unsupported platform: $(uname -s)" | ||
fi | ||
} | ||
|
||
arch_detect() { | ||
if [ "$(uname -m)" = "x86_64" ]; then | ||
ARCH="x86_64" | ||
elif [ "$(uname -m)" = "aarch64" ]; then # Linux uname output | ||
ARCH="aarch64" | ||
elif [ "$(uname -m)" = "arm64" ]; then # Darwin uname output | ||
ARCH="aarch64" | ||
else | ||
error "Unsupported architecture: $(uname -m)" | ||
fi | ||
} | ||
|
||
checksum() { | ||
if command -v sha256sum >/dev/null; then | ||
sha256sum "$1" | ||
else | ||
shasum -a 256 "$1" | ||
fi | ||
} | ||
|
||
downloader() { | ||
if command -v curl >/dev/null; then | ||
curl -L -o "$2" "$1" | ||
else | ||
wget -O "$2" "$1" | ||
fi | ||
} | ||
|
||
extract() { | ||
unzip -o "$1" -d "$2" | ||
} | ||
|
||
download_bws() { | ||
bws_url="https://github.com/bitwarden/sdk/releases/download/bws-v${BWS_VERSION}/bws-${ARCH}-${PLATFORM}-${BWS_VERSION}.zip" | ||
echo "Downloading bws from: $bws_url" | ||
tmp_dir="$(mktemp -d)" | ||
downloader "$bws_url" "$tmp_dir/bws.zip" | ||
} | ||
|
||
validate_checksum() { | ||
checksum_url="https://github.com/bitwarden/sdk/releases/download/bws-v${BWS_VERSION}/bws-sha256-checksums-${BWS_VERSION}.txt" | ||
echo "Downloading checksum file from: $checksum_url" | ||
checksum_file="$tmp_dir/bws-checksums.txt" | ||
downloader "$checksum_url" "$checksum_file" | ||
|
||
expected_checksum="$(grep "bws-${ARCH}-${PLATFORM}-${BWS_VERSION}.zip" "$checksum_file" | awk '{print $1}')" | ||
actual_checksum="$(checksum "$tmp_dir/bws.zip" | awk '{print $1}')" | ||
|
||
if [ "$actual_checksum" != "$expected_checksum" ]; then | ||
error "Checksum validation failed. Expected: $expected_checksum, Actual: $actual_checksum" | ||
else | ||
echo "Checksum validation successful." | ||
fi | ||
} | ||
|
||
install_bws() { | ||
echo "Installing bws..." | ||
extract "$tmp_dir/bws.zip" "$tmp_dir" | ||
chmod +x "$tmp_dir/bws" | ||
|
||
if can_sudo; then | ||
sudo install -m 755 "$tmp_dir/bws" /usr/local/bin/bws | ||
|
||
if ! command -v bws >/dev/null; then | ||
error "Installation failed. bws was not found in /usr/local/bin" | ||
fi | ||
|
||
echo "bws installed to /usr/local/bin/bws" | ||
else | ||
echo "Installing to your \$HOME directory..." | ||
user_bin_dir="${HOME}/.local/bin" | ||
mkdir -p "${user_bin_dir}" | ||
install -m 755 "$tmp_dir/bws" "${user_bin_dir}/bws" | ||
|
||
if ! command -v "${user_bin_dir}/bws" >/dev/null; then | ||
error "Installation failed. bws was not found in ${user_bin_dir}" | ||
fi | ||
|
||
echo "bws installed at ${user_bin_dir}/bws" | ||
echo "Please add ${user_bin_dir} to your PATH by adding the following line to your ~/.profile or shell rc file:" | ||
echo "export PATH=\"\$PATH:${user_bin_dir}\"" | ||
fi | ||
|
||
rm -rf "$tmp_dir" | ||
} | ||
|
||
uninstall_bws() { | ||
if command -v bws >/dev/null; then | ||
echo "Uninstalling bws..." | ||
if can_sudo; then | ||
sudo rm "$(command -v bws)" | ||
else | ||
rm "$(command -v bws)" | ||
fi | ||
|
||
# Safely remove the configuration directory | ||
if [ -n "$HOME" ]; then | ||
echo "Removing bws configuration directory at ${HOME}/.bws" | ||
echo "If you use another directory for your configuration, you may want to remove it manually." | ||
rm -rf "${HOME}/.bws" | ||
else | ||
echo "HOME environment variable is not set. Cannot safely remove .bws directory." | ||
fi | ||
|
||
echo "bws uninstalled successfully." | ||
else | ||
echo "bws is not installed." | ||
fi | ||
exit 0 | ||
} | ||
|
||
main "$@" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think the
Hash
fromGet-FileHash
is uppercase, while the GH checksum file is lowercase, so they would not match.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell, PowerShell is case-insensitive, where possible. I found this, which says that this is also the case for comparison operators, so the comparison should return
true
, despite being in different cases.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding testing on Windows: I have tested it sparingly in a VM a few times throughout updating the script using
iwr <url-for-raw-file> | iex
, and it seems to be working.I haven't been able to test it much on x86_64 though, as the only Windows machine in my house is a VM on my M2 Mac.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Windows as always have to be unique. Indeed it seems that string comparison is case insensitive, which is mind blowing to me 🤯
Thank you for the insights into testing, i wondered how do you test out Windows on Mac. 👍