From ecba0cd9302839daf61d4e63d14534d4f9659f1f Mon Sep 17 00:00:00 2001 From: nobrainghost Date: Sun, 15 Jun 2025 15:16:20 +0300 Subject: [PATCH 1/3] fixes --- go-up.sh | 187 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 134 insertions(+), 53 deletions(-) diff --git a/go-up.sh b/go-up.sh index 253848a..2e97983 100755 --- a/go-up.sh +++ b/go-up.sh @@ -1,113 +1,194 @@ #!/bin/bash +# Fixes: destructive operations, pipeline errors, permission handling, download verification + +set -euo pipefail + SUDOCMD="" WGETCMD="wget -qO-" CURLCMD="curl -sL" -EXTRACTCMD="tar -xzf - --strip-components=1 -C" -GOBIN=$(which go 2> /dev/null) +# FIX: Added cleanup for temporary files to prevent disk space issues +cleanup() { + [[ -n "${TEMP_DIR:-}" ]] && [[ -d "$TEMP_DIR" ]] && rm -rf "$TEMP_DIR" + [[ -n "${TEMP_FILE:-}" ]] && [[ -f "$TEMP_FILE" ]] && rm -f "$TEMP_FILE" +} +trap cleanup EXIT -if [[ -z "$GOBIN" ]] -then +# FIX: Improved error handling for Go detection +set +e +GOBIN=$(which go 2>/dev/null) +set -e + +if [[ -z "$GOBIN" ]]; then echo "❌ Go not installed, nothing to update" exit 1 fi -GOROOT=$($GOBIN env GOROOT 2> /dev/null) -GOPATH=$($GOBIN env GOPATH 2> /dev/null) +GOROOT=$($GOBIN env GOROOT 2>/dev/null) || true +GOPATH=$($GOBIN env GOPATH 2>/dev/null) || true -if [[ -z "$GOROOT" ]] -then - echo "❌ Could't find \$GOROOT environment variable" +if [[ -z "$GOROOT" ]]; then + echo "❌ Couldn't find \$GOROOT environment variable" exit 1 fi -GOVERSION=$($GOBIN env GOVERSION 2> /dev/null) +GOVERSION=$($GOBIN env GOVERSION 2>/dev/null) || true GOVERSIONPRETTY=${GOVERSION#"go"} -if [[ -z "$GOVERSION" ]] -then - echo "❌ Could't find \$GOVERSION environment variable" +if [[ -z "$GOVERSION" ]]; then + echo "❌ Couldn't find \$GOVERSION environment variable" exit 1 fi -if [[ -z "$(which wget 2> /dev/null)" ]] && [[ -z "$(which curl 2> /dev/null)" ]] -then +echo "✅ Found Go $GOVERSIONPRETTY installed at $GOROOT" + +if [[ -z "$(which wget 2>/dev/null)" ]] && [[ -z "$(which curl 2>/dev/null)" ]]; then echo "❌ Unable to update go to latest version, please install wget or curl" exit 1 fi +echo "🌐 Checking for latest Go version..." + +# FIX: Clean version detection with proper parsing to remove the extra timestamp GOLATESTURL="https://go.dev/VERSION?m=text" -GOLATEST=$($WGETCMD "$GOLATESTURL" 2> /dev/null || $CURLCMD "$GOLATESTURL" 2> /dev/null) +set +e +GOLATEST=$($WGETCMD "$GOLATESTURL" 2>/dev/null | head -n1 || $CURLCMD "$GOLATESTURL" 2>/dev/null | head -n1) +set -e GOLATESTPRETTY=${GOLATEST#"go"} -if [[ -z "$GOLATEST" ]] -then - echo "❌ Could't fetch latest golang version" +# Validate we got a version +if [[ -z "$GOLATEST" ]]; then + echo "❌ Couldn't fetch latest golang version" + echo " Please check your internet connection" exit 1 fi -if [[ "$GOVERSION" == "$GOLATEST" ]] -then +# Check if update is needed +if [[ "$GOVERSION" == "$GOLATEST" ]]; then echo "👍 You already have the latest go with version $GOVERSIONPRETTY, no update required" exit 0 fi +echo "📋 Update available: Go $GOVERSIONPRETTY → Go $GOLATESTPRETTY" + +# Detect GOROOT ownership for permission handling case $(uname) in - Linux) GOROOTOWNER=$(stat -c "%U" $GOROOT 2> /dev/null) ;; - Darwin) GOROOTOWNER=$(stat -f "%Su" $GOROOT 2> /dev/null) ;; + Linux) GOROOTOWNER=$(stat -c "%U" $GOROOT 2>/dev/null) || true ;; + Darwin) GOROOTOWNER=$(stat -f "%Su" $GOROOT 2>/dev/null) || true ;; esac -if [[ -z "$GOROOTOWNER" ]] -then - echo "❌ Could't find owner of the \$GOROOT directory" +if [[ -z "$GOROOTOWNER" ]]; then + echo "❌ Couldn't find owner of the \$GOROOT directory" exit 1 fi -if [[ "$USER" != "$GOROOTOWNER" ]] -then - echo "🔥 Requires "$GOROOTOWNER" user access rights ..." +# FIX: Improved sudo handling with proper validation +if [[ "$USER" != "$GOROOTOWNER" ]]; then + echo "🔥 Requires $GOROOTOWNER user access rights ..." - SUDOCMD="sudo -u $GOROOTOWNER" - $SUDOCMD echo -n "" + if [[ "$GOROOTOWNER" == "root" ]]; then + SUDOCMD="sudo" + else + SUDOCMD="sudo -u $GOROOTOWNER" + fi + + # Test sudo access properly + if ! $SUDOCMD true; then + echo "❌ Cannot execute commands as $GOROOTOWNER" + exit 1 + fi + + # Test write permissions to GOROOT + if ! $SUDOCMD touch "$GOROOT/.test_write"; then + echo "❌ Cannot write to $GOROOT even with sudo" + exit 1 + fi + $SUDOCMD rm -f "$GOROOT/.test_write" fi -GOARCH=$($GOBIN env GOARCH 2> /dev/null) +GOARCH=$($GOBIN env GOARCH 2>/dev/null) || true -if [[ -z "$GOARCH" ]] -then - echo "❌ Could't find \$GOARCH environment variable" +if [[ -z "$GOARCH" ]]; then + echo "❌ Couldn't find \$GOARCH environment variable" exit 1 fi -GOOS=$($GOBIN env GOOS 2> /dev/null) +GOOS=$($GOBIN env GOOS 2>/dev/null) || true -if [[ -z "$GOOS" ]] -then - echo "❌ Could't find \$GOOS environment variable" +if [[ -z "$GOOS" ]]; then + echo "❌ Couldn't find \$GOOS environment variable" exit 1 fi GOTARBALL="https://go.dev/dl/$GOLATEST.$GOOS-$GOARCH.tar.gz" -$SUDOCMD rm -rf "$GOROOT"/* -$WGETCMD $GOTARBALL 2> /dev/null | $SUDOCMD $EXTRACTCMD $GOROOT 2> /dev/null +echo "📥 Downloading Go $GOLATESTPRETTY..." -if [[ "$?" != "0" ]] -then - $SUDOCMD rm -rf "$GOROOT"/* - $CURLCMD $GOTARBALL 2> /dev/null | $SUDOCMD $EXTRACTCMD $GOROOT 2> /dev/null +# FIX: Safe download to temp location with progress bars +TEMP_DIR=$(mktemp -d) +TEMP_FILE=$(mktemp) - if [[ "$?" != "0" ]] - then - echo "❌ Couldn't download and unpack go with version $GOLATESTPRETTY" - exit 1 +download_success=false +if command -v wget >/dev/null 2>&1; then + echo "Using wget to download..." + if wget --progress=bar:force -O "$TEMP_FILE" "$GOTARBALL" 2>&1; then + download_success=true + fi +elif command -v curl >/dev/null 2>&1; then + echo "Using curl to download..." + if curl --progress-bar -L -o "$TEMP_FILE" "$GOTARBALL"; then + download_success=true fi fi -if [[ -n "$GOPATH" ]] && [[ "$GOPATH" == "$GOROOT"* ]] -then - $SUDOCMD mkdir -p $GOPATH +if [[ "$download_success" != "true" ]]; then + echo "❌ Failed to download Go $GOLATESTPRETTY" + exit 1 fi -echo "👍 Go successfully upgraded from version $GOVERSIONPRETTY to version $GOLATESTPRETTY" +echo "✅ Download completed successfully!" + +echo "📦 Extracting and verifying Go $GOLATESTPRETTY..." + +# FIX: Extract to temp and verify before installing +if ! tar -xzf "$TEMP_FILE" -C "$TEMP_DIR"; then + echo "❌ Failed to extract Go tarball" + exit 1 +fi + +# Verify the extracted Go installation works +if ! "$TEMP_DIR/go/bin/go" version >/dev/null 2>&1; then + echo "❌ Downloaded Go installation is not working" + exit 1 +fi + +echo "🔄 Installing Go $GOLATESTPRETTY..." + +# FIX: Atomic replacement with rollback capability +if [[ -d "$GOROOT" ]]; then + OLD_GOROOT="${GOROOT}.old.$$" + $SUDOCMD mv "$GOROOT" "$OLD_GOROOT" +else + OLD_GOROOT="" +fi + +if $SUDOCMD mv "$TEMP_DIR/go" "$GOROOT"; then + # Verify new installation works in its final location + if "$GOROOT/bin/go" version >/dev/null 2>&1; then + [[ -n "$OLD_GOROOT" ]] && $SUDOCMD rm -rf "$OLD_GOROOT" + echo "✅ Go successfully upgraded from version $GOVERSIONPRETTY to version $GOLATESTPRETTY" + else + # Rollback on verification failure + echo "❌ New Go installation failed verification, rolling back..." + $SUDOCMD rm -rf "$GOROOT" + [[ -n "$OLD_GOROOT" ]] && $SUDOCMD mv "$OLD_GOROOT" "$GOROOT" + echo "❌ Rollback completed, Go $GOVERSIONPRETTY restored" + exit 1 + fi +else + # Restore old installation if move failed + echo "❌ Failed to install new Go version, restoring previous installation..." + [[ -n "$OLD_GOROOT" ]] && $SUDOCMD mv "$OLD_GOROOT" "$GOROOT" + exit 1 +fi From 33c8458c7be571d8e7d8313bbf906e3da43ce684 Mon Sep 17 00:00:00 2001 From: Benar! Date: Sun, 15 Jun 2025 15:18:35 +0300 Subject: [PATCH 2/3] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index c443679..ab5ca1f 100644 --- a/README.md +++ b/README.md @@ -26,4 +26,3 @@ wget -qO- https://raw.githubusercontent.com/DieTime/go-up/master/go-up.sh | bash - Works with either curl or wget on the system - Automatically determines the path to install a new version - Restores the GOPATH folder if it is inside GOROOT -- Does not use temporary files From b9a6e2bf91504c76260c4221f52da305d65d380e Mon Sep 17 00:00:00 2001 From: Benar! Date: Fri, 20 Jun 2025 10:36:52 +0300 Subject: [PATCH 3/3] remove unnecessary comments --- go-up.sh | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/go-up.sh b/go-up.sh index 2e97983..d92af32 100755 --- a/go-up.sh +++ b/go-up.sh @@ -1,6 +1,5 @@ #!/bin/bash -# Fixes: destructive operations, pipeline errors, permission handling, download verification set -euo pipefail @@ -8,14 +7,12 @@ SUDOCMD="" WGETCMD="wget -qO-" CURLCMD="curl -sL" -# FIX: Added cleanup for temporary files to prevent disk space issues cleanup() { [[ -n "${TEMP_DIR:-}" ]] && [[ -d "$TEMP_DIR" ]] && rm -rf "$TEMP_DIR" [[ -n "${TEMP_FILE:-}" ]] && [[ -f "$TEMP_FILE" ]] && rm -f "$TEMP_FILE" } trap cleanup EXIT -# FIX: Improved error handling for Go detection set +e GOBIN=$(which go 2>/dev/null) set -e @@ -50,7 +47,6 @@ fi echo "🌐 Checking for latest Go version..." -# FIX: Clean version detection with proper parsing to remove the extra timestamp GOLATESTURL="https://go.dev/VERSION?m=text" set +e GOLATEST=$($WGETCMD "$GOLATESTURL" 2>/dev/null | head -n1 || $CURLCMD "$GOLATESTURL" 2>/dev/null | head -n1) @@ -64,7 +60,6 @@ if [[ -z "$GOLATEST" ]]; then exit 1 fi -# Check if update is needed if [[ "$GOVERSION" == "$GOLATEST" ]]; then echo "👍 You already have the latest go with version $GOVERSIONPRETTY, no update required" exit 0 @@ -83,7 +78,6 @@ if [[ -z "$GOROOTOWNER" ]]; then exit 1 fi -# FIX: Improved sudo handling with proper validation if [[ "$USER" != "$GOROOTOWNER" ]]; then echo "🔥 Requires $GOROOTOWNER user access rights ..." @@ -93,13 +87,11 @@ if [[ "$USER" != "$GOROOTOWNER" ]]; then SUDOCMD="sudo -u $GOROOTOWNER" fi - # Test sudo access properly if ! $SUDOCMD true; then echo "❌ Cannot execute commands as $GOROOTOWNER" exit 1 fi - # Test write permissions to GOROOT if ! $SUDOCMD touch "$GOROOT/.test_write"; then echo "❌ Cannot write to $GOROOT even with sudo" exit 1 @@ -125,7 +117,6 @@ GOTARBALL="https://go.dev/dl/$GOLATEST.$GOOS-$GOARCH.tar.gz" echo "📥 Downloading Go $GOLATESTPRETTY..." -# FIX: Safe download to temp location with progress bars TEMP_DIR=$(mktemp -d) TEMP_FILE=$(mktemp) @@ -151,13 +142,11 @@ echo "✅ Download completed successfully!" echo "📦 Extracting and verifying Go $GOLATESTPRETTY..." -# FIX: Extract to temp and verify before installing if ! tar -xzf "$TEMP_FILE" -C "$TEMP_DIR"; then echo "❌ Failed to extract Go tarball" exit 1 fi -# Verify the extracted Go installation works if ! "$TEMP_DIR/go/bin/go" version >/dev/null 2>&1; then echo "❌ Downloaded Go installation is not working" exit 1 @@ -165,7 +154,7 @@ fi echo "🔄 Installing Go $GOLATESTPRETTY..." -# FIX: Atomic replacement with rollback capability +# Atomic replacement with rollback capability if [[ -d "$GOROOT" ]]; then OLD_GOROOT="${GOROOT}.old.$$" $SUDOCMD mv "$GOROOT" "$OLD_GOROOT" @@ -174,12 +163,12 @@ else fi if $SUDOCMD mv "$TEMP_DIR/go" "$GOROOT"; then - # Verify new installation works in its final location + # Verify new installation works if "$GOROOT/bin/go" version >/dev/null 2>&1; then [[ -n "$OLD_GOROOT" ]] && $SUDOCMD rm -rf "$OLD_GOROOT" echo "✅ Go successfully upgraded from version $GOVERSIONPRETTY to version $GOLATESTPRETTY" else - # Rollback on verification failure + # Rollback on failure echo "❌ New Go installation failed verification, rolling back..." $SUDOCMD rm -rf "$GOROOT" [[ -n "$OLD_GOROOT" ]] && $SUDOCMD mv "$OLD_GOROOT" "$GOROOT"