feat: improve source build installation experience

- Remove confusing --main flag, use --source for clarity
- Fix timeout issues when building from source in LXC containers
  - Increase timeout from 5min to 20min for source builds
  - Add PULSE_CONTAINER_TIMEOUT env var for custom timeouts
  - Support PULSE_CONTAINER_TIMEOUT=0 to disable timeout
- Fix misleading "Latest version: vX.X.X" message during source builds
- Update documentation to use --source instead of --main
- Simplify auto-update script logic for source builds

Changes:
- install.sh: Check BUILD_FROM_SOURCE early to skip version detection
- install.sh: Adaptive timeout (300s binary, 1200s source builds)
- install.sh: Better timeout error messages with recovery instructions
- README.md: Replace --main with --source in examples
- docs/INSTALL.md: Replace --main with --source in examples
- scripts/pulse-auto-update.sh: Remove --main special case
This commit is contained in:
rcourtman 2025-10-21 08:57:29 +00:00
parent 56c6c0cc0c
commit b929fdcc6e
4 changed files with 282 additions and 322 deletions

View file

@ -83,7 +83,7 @@ curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | b
docker run -d -p 7655:7655 -v pulse_data:/data rcourtman/pulse:latest
# Testing: Install from main branch source (for testing latest fixes)
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- --main
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- --source
# Alternative: Kubernetes (Helm)
helm registry login ghcr.io

View file

@ -176,7 +176,7 @@ curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | b
Build and install directly from the main branch to test the latest fixes before they're released:
```bash
# Install from main branch (latest development code)
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- --main
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- --source
# Install from a specific branch
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- --source develop

View file

@ -26,6 +26,7 @@ FORCE_VERSION=""
FORCE_CHANNEL=""
SOURCE_BRANCH="main"
PROXY_MODE="" # Can be: yes, no, auto, or empty (will prompt)
BUILD_FROM_SOURCE_MARKER="$INSTALL_DIR/BUILD_FROM_SOURCE"
DEBIAN_TEMPLATE_FALLBACK="debian-12-standard_12.12-1_amd64.tar.zst"
DEBIAN_TEMPLATE=""
@ -1111,7 +1112,7 @@ create_lxc_container() {
install_cmd="$install_cmd $auto_updates_flag"
fi
if [[ "$BUILD_FROM_SOURCE" == "true" ]]; then
install_cmd="$install_cmd --main"
install_cmd="$install_cmd --source '$SOURCE_BRANCH'"
fi
if [[ "$frontend_port" != "7655" ]]; then
install_cmd="FRONTEND_PORT=$frontend_port $install_cmd"
@ -1120,14 +1121,33 @@ create_lxc_container() {
# Run installation showing output in real-time so users can see progress/errors
# Use timeout wrapper if available
local install_status
if command -v timeout >/dev/null 2>&1; then
local timeout_duration=300
if [[ "$BUILD_FROM_SOURCE" == "true" ]]; then
timeout_duration=1200
fi
if [[ -n "${PULSE_CONTAINER_TIMEOUT:-}" ]]; then
if [[ "${PULSE_CONTAINER_TIMEOUT}" =~ ^[0-9]+$ ]]; then
timeout_duration=${PULSE_CONTAINER_TIMEOUT}
else
print_warn "Ignoring invalid PULSE_CONTAINER_TIMEOUT value '${PULSE_CONTAINER_TIMEOUT}'"
fi
fi
if command -v timeout >/dev/null 2>&1 && [[ "$timeout_duration" -ne 0 ]]; then
# Show output in real-time with timeout
timeout 300 pct exec $CTID -- bash -c "$install_cmd"
timeout "$timeout_duration" pct exec $CTID -- bash -c "$install_cmd"
install_status=$?
if [[ $install_status -eq 124 ]]; then
print_error "Installation timed out after 5 minutes"
print_info "This usually happens due to network issues or GitHub rate limiting"
print_info "You can enter the container and run 'bash /tmp/install.sh' manually:"
print_error "Installation timed out after ${timeout_duration}s"
if [[ "$BUILD_FROM_SOURCE" == "true" ]]; then
print_info "Building from source can take more than 15 minutes in containers, especially on first run."
else
print_info "This usually happens due to network issues or GitHub rate limiting."
fi
print_info "You can increase or disable the timeout by setting PULSE_CONTAINER_TIMEOUT (set to 0 to disable)."
print_info "Then enter the container and run 'bash /tmp/install.sh' manually:"
print_info " pct enter $CTID"
cleanup_on_error
fi
@ -1365,13 +1385,22 @@ backup_existing() {
}
download_pulse() {
# Check if we should build from source - do this FIRST to avoid confusing version messages
if [[ "$BUILD_FROM_SOURCE" == "true" ]]; then
if ! build_from_source "$SOURCE_BRANCH"; then
print_error "Source build failed"
exit 1
fi
return 0
fi
print_info "Downloading Pulse..."
# Check for forced version first
if [[ -n "${FORCE_VERSION}" ]]; then
LATEST_RELEASE="${FORCE_VERSION}"
print_info "Installing specific version: $LATEST_RELEASE"
# Verify the version exists (with timeout)
if command -v timeout >/dev/null 2>&1; then
if ! timeout 15 curl -fsS --connect-timeout 10 --max-time 30 "https://api.github.com/repos/$GITHUB_REPO/releases/tags/$LATEST_RELEASE" > /dev/null 2>&1; then
@ -1386,7 +1415,7 @@ download_pulse() {
# UPDATE_CHANNEL should already be set by main(), but set default if not
if [[ -z "${UPDATE_CHANNEL:-}" ]]; then
UPDATE_CHANNEL="stable"
# Allow override via command line
if [[ -n "${FORCE_CHANNEL}" ]]; then
UPDATE_CHANNEL="${FORCE_CHANNEL}"
@ -1399,7 +1428,7 @@ download_pulse() {
fi
fi
fi
# Get appropriate release based on channel (with timeout)
if [[ "$UPDATE_CHANNEL" == "rc" ]]; then
# Get all releases and find the latest (including pre-releases)
@ -1418,7 +1447,7 @@ download_pulse() {
LATEST_RELEASE=$(curl -s --connect-timeout 10 --max-time 30 https://api.github.com/repos/$GITHUB_REPO/releases/latest 2>/dev/null | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' || true)
fi
fi
# Fallback: Try direct GitHub redirect if API fails
if [[ -z "$LATEST_RELEASE" ]]; then
print_info "GitHub API unavailable, trying alternative method..."
@ -1428,166 +1457,24 @@ download_pulse() {
LATEST_RELEASE=$(curl -sI --connect-timeout 5 --max-time 10 https://github.com/$GITHUB_REPO/releases/latest 2>/dev/null | grep -i '^location:' | sed -E 's|.*tag/([^[:space:]]+).*|\1|' | tr -d '\r' || true)
fi
fi
# Final fallback: Use a known good version
if [[ -z "$LATEST_RELEASE" ]]; then
print_warn "Could not determine latest release from GitHub, using fallback version"
LATEST_RELEASE="v4.5.1" # Known stable version as fallback
fi
print_info "Latest version: $LATEST_RELEASE"
fi
# Check if we should build from source
if [[ "$BUILD_FROM_SOURCE" == "true" ]]; then
print_info "Building Pulse from source (branch: $SOURCE_BRANCH)..."
# Install build dependencies
print_info "Installing build dependencies..."
if ! (apt-get update >/dev/null 2>&1 && apt-get install -y git make nodejs npm wget >/dev/null 2>&1); then
print_error "Failed to install build dependencies"
exit 1
fi
# Check Go version and install newer version if needed
GO_MIN_VERSION="1.24"
GO_INSTALLED=false
if command -v go >/dev/null 2>&1; then
GO_VERSION=$(go version | grep -oE '[0-9]+\.[0-9]+' | head -1)
if [[ "$(printf '%s\n' "$GO_MIN_VERSION" "$GO_VERSION" | sort -V | head -n1)" == "$GO_MIN_VERSION" ]]; then
GO_INSTALLED=true
print_info "Go $GO_VERSION is installed (meets minimum $GO_MIN_VERSION)"
fi
fi
if [[ "$GO_INSTALLED" != "true" ]]; then
print_info "Installing Go 1.24 (system Go is too old or missing)..."
# Detect architecture for Go download
ARCH=$(uname -m)
case $ARCH in
x86_64)
GO_ARCH="amd64"
;;
aarch64)
GO_ARCH="arm64"
;;
armv7l)
GO_ARCH="armv6l"
;;
*)
print_error "Unsupported architecture for Go: $ARCH"
exit 1
;;
esac
cd /tmp
wget -q "https://go.dev/dl/go1.24.7.linux-${GO_ARCH}.tar.gz"
rm -rf /usr/local/go
tar -C /usr/local -xzf "go1.24.7.linux-${GO_ARCH}.tar.gz"
export PATH=/usr/local/go/bin:$PATH
rm "go1.24.7.linux-${GO_ARCH}.tar.gz"
fi
# Create temp directory for build
TEMP_BUILD="/tmp/pulse-build-$$"
mkdir -p "$TEMP_BUILD"
cd "$TEMP_BUILD"
print_info "Cloning repository (branch: $SOURCE_BRANCH)..."
if ! git clone --depth 1 --branch "$SOURCE_BRANCH" "https://github.com/$GITHUB_REPO.git" >/dev/null 2>&1; then
print_error "Failed to clone repository (branch: $SOURCE_BRANCH)"
print_info "Make sure the branch exists and is accessible"
exit 1
fi
cd Pulse
print_info "Building frontend..."
cd frontend-modern
if ! (npm ci >/dev/null 2>&1 && npm run build >/dev/null 2>&1); then
print_error "Failed to build frontend"
exit 1
fi
cd ..
print_info "Building backend..."
# Ensure Go is in PATH for the build
export PATH=/usr/local/go/bin:$PATH
if ! make build >/dev/null 2>&1; then
print_error "Failed to build backend"
exit 1
fi
# Detect and stop existing service BEFORE installing new binary
EXISTING_SERVICE=$(detect_service_name)
if timeout 5 systemctl is-active --quiet $EXISTING_SERVICE 2>/dev/null; then
print_info "Stopping existing Pulse service ($EXISTING_SERVICE)..."
safe_systemctl stop $EXISTING_SERVICE || true
sleep 2 # Give the process time to fully stop and release the binary
fi
# Ensure install directory and bin subdirectory exist
mkdir -p "$INSTALL_DIR/bin"
# Copy the built binary
if [[ -f "$INSTALL_DIR/bin/pulse" ]]; then
mv "$INSTALL_DIR/bin/pulse" "$INSTALL_DIR/bin/pulse.old" 2>/dev/null || true
fi
if ! cp pulse "$INSTALL_DIR/bin/pulse"; then
print_error "Failed to copy built binary to $INSTALL_DIR/bin/pulse"
if [[ -f "$INSTALL_DIR/bin/pulse.old" ]]; then
mv "$INSTALL_DIR/bin/pulse.old" "$INSTALL_DIR/bin/pulse"
fi
exit 1
fi
chmod +x "$INSTALL_DIR/bin/pulse"
print_info "Building Docker agent from source..."
agent_version=$(git describe --tags --always --dirty 2>/dev/null || echo "dev")
if ! go build -ldflags="-X github.com/rcourtman/pulse-go-rewrite/internal/dockeragent.Version=${agent_version}" -o pulse-docker-agent ./cmd/pulse-docker-agent >/dev/null 2>&1; then
print_error "Failed to build Docker agent binary"
exit 1
fi
cp -f pulse-docker-agent "$INSTALL_DIR/pulse-docker-agent"
cp -f pulse-docker-agent "$INSTALL_DIR/bin/pulse-docker-agent"
chmod +x "$INSTALL_DIR/pulse-docker-agent" "$INSTALL_DIR/bin/pulse-docker-agent"
chown -R pulse:pulse "$INSTALL_DIR"
ln -sf "$INSTALL_DIR/bin/pulse-docker-agent" /usr/local/bin/pulse-docker-agent
rm -f pulse-docker-agent
print_info "Building temperature proxy from source..."
if ! go build -o pulse-sensor-proxy ./cmd/pulse-sensor-proxy >/dev/null 2>&1; then
print_error "Failed to build temperature proxy binary"
exit 1
fi
cp -f pulse-sensor-proxy "$INSTALL_DIR/bin/pulse-sensor-proxy"
chmod +x "$INSTALL_DIR/bin/pulse-sensor-proxy"
chown pulse:pulse "$INSTALL_DIR/bin/pulse-sensor-proxy"
rm -f pulse-sensor-proxy
build_agent_binaries_from_source "$agent_version"
# Update VERSION file to show it's from source
echo "$SOURCE_BRANCH-$(git rev-parse --short HEAD)" > "$INSTALL_DIR/VERSION"
# Cleanup
cd /
rm -rf "$TEMP_BUILD"
print_success "Successfully built and installed Pulse from source (branch: $SOURCE_BRANCH)"
# Skip the rest of the download/install logic
SKIP_DOWNLOAD=true
if [[ "$BUILD_FROM_SOURCE" == "true" && "$SKIP_DOWNLOAD" != "true" ]]; then
print_error "Source build requested but download path was reached (internal error)"
exit 1
fi
# Only do download if not building from source
if [[ "$SKIP_DOWNLOAD" != "true" ]]; then
rm -f "$BUILD_FROM_SOURCE_MARKER"
# Detect architecture
ARCH=$(uname -m)
case $ARCH in
@ -1898,6 +1785,205 @@ build_agent_binaries_from_source() {
done
}
build_from_source() {
local branch="${1:-main}"
local original_dir
original_dir=$(pwd)
local temp_build=""
local GO_MIN_VERSION="1.24"
local GO_INSTALLED=false
local arch=""
local go_arch=""
local agent_version=""
local service_name=""
print_info "Building Pulse from source (branch: $branch)..."
print_info "Installing build dependencies..."
if ! (apt-get update >/dev/null 2>&1 && apt-get install -y git make nodejs npm wget >/dev/null 2>&1); then
print_error "Failed to install build dependencies"
return 1
fi
if command -v go >/dev/null 2>&1; then
local GO_VERSION
GO_VERSION=$(go version | awk '{print $3}' | sed 's/go//')
if [[ "$(printf '%s\n' "$GO_MIN_VERSION" "$GO_VERSION" | sort -V | head -n1)" == "$GO_MIN_VERSION" ]]; then
GO_INSTALLED=true
print_info "Go $GO_VERSION is installed (meets minimum $GO_MIN_VERSION)"
else
print_info "Go $GO_VERSION is too old. Installing Go $GO_MIN_VERSION..."
fi
fi
if [[ "$GO_INSTALLED" != "true" ]]; then
arch=$(uname -m)
case "$arch" in
x86_64)
go_arch="amd64"
;;
aarch64)
go_arch="arm64"
;;
armv7l)
go_arch="armv6l"
;;
*)
print_error "Unsupported architecture for Go: $arch"
return 1
;;
esac
if ! cd /tmp; then
print_error "Failed to prepare Go installation directory"
cd "$original_dir" >/dev/null 2>&1 || true
return 1
fi
if ! wget -q "https://go.dev/dl/go1.24.7.linux-${go_arch}.tar.gz"; then
print_error "Failed to download Go toolchain"
cd "$original_dir" >/dev/null 2>&1 || true
return 1
fi
rm -rf /usr/local/go
if ! tar -C /usr/local -xzf "go1.24.7.linux-${go_arch}.tar.gz"; then
print_error "Failed to extract Go toolchain"
rm -f "go1.24.7.linux-${go_arch}.tar.gz"
cd "$original_dir" >/dev/null 2>&1 || true
return 1
fi
rm -f "go1.24.7.linux-${go_arch}.tar.gz"
cd "$original_dir" >/dev/null 2>&1 || true
fi
export PATH=/usr/local/go/bin:$PATH
temp_build=$(mktemp -d /tmp/pulse-build-XXXXXX)
if [[ ! -d "$temp_build" ]]; then
print_error "Failed to create temporary build directory"
return 1
fi
if ! git clone --depth 1 --branch "$branch" "https://github.com/$GITHUB_REPO.git" "$temp_build/Pulse" >/dev/null 2>&1; then
print_error "Failed to clone repository (branch: $branch)"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
if ! cd "$temp_build/Pulse"; then
print_error "Failed to enter source checkout"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
if ! cd frontend-modern; then
print_error "Frontend directory missing in repository"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
if ! npm ci >/dev/null 2>&1; then
print_warn "npm ci failed, falling back to npm install..."
if ! npm install >/dev/null 2>&1; then
print_error "Failed to install frontend dependencies"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
fi
if ! npm run build >/dev/null 2>&1; then
print_error "Failed to build frontend"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
cd ..
if ! make build >/dev/null 2>&1; then
print_error "Failed to build backend"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
service_name=$(detect_service_name)
if timeout 5 systemctl is-active --quiet "$service_name" 2>/dev/null; then
print_info "Stopping existing Pulse service ($service_name)..."
safe_systemctl stop "$service_name" || true
sleep 2
fi
mkdir -p "$INSTALL_DIR/bin" "$INSTALL_DIR/scripts"
if [[ -f "$INSTALL_DIR/bin/pulse" ]]; then
mv "$INSTALL_DIR/bin/pulse" "$INSTALL_DIR/bin/pulse.old" 2>/dev/null || true
fi
if ! cp pulse "$INSTALL_DIR/bin/pulse"; then
print_error "Failed to copy built Pulse binary"
[[ -f "$INSTALL_DIR/bin/pulse.old" ]] && mv "$INSTALL_DIR/bin/pulse.old" "$INSTALL_DIR/bin/pulse"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
chmod +x "$INSTALL_DIR/bin/pulse"
agent_version=$(git describe --tags --always --dirty 2>/dev/null || echo "dev")
if ! go build -ldflags="-X github.com/rcourtman/pulse-go-rewrite/internal/dockeragent.Version=${agent_version}" -o pulse-docker-agent ./cmd/pulse-docker-agent >/dev/null 2>&1; then
print_error "Failed to build Docker agent binary"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
cp -f pulse-docker-agent "$INSTALL_DIR/pulse-docker-agent"
cp -f pulse-docker-agent "$INSTALL_DIR/bin/pulse-docker-agent"
chmod +x "$INSTALL_DIR/pulse-docker-agent" "$INSTALL_DIR/bin/pulse-docker-agent"
ln -sf "$INSTALL_DIR/bin/pulse-docker-agent" /usr/local/bin/pulse-docker-agent
rm -f pulse-docker-agent
if ! go build -o pulse-sensor-proxy ./cmd/pulse-sensor-proxy >/dev/null 2>&1; then
print_error "Failed to build temperature proxy binary"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
return 1
fi
cp -f pulse-sensor-proxy "$INSTALL_DIR/bin/pulse-sensor-proxy"
chmod +x "$INSTALL_DIR/bin/pulse-sensor-proxy"
rm -f pulse-sensor-proxy
build_agent_binaries_from_source "$agent_version"
for script_name in install-docker-agent.sh install-docker.sh install-sensor-proxy.sh; do
if [[ -f "scripts/$script_name" ]]; then
cp "scripts/$script_name" "$INSTALL_DIR/scripts/$script_name"
chmod 755 "$INSTALL_DIR/scripts/$script_name"
fi
done
ln -sf "$INSTALL_DIR/bin/pulse" /usr/local/bin/pulse
echo "$branch-$(git rev-parse --short HEAD)" > "$INSTALL_DIR/VERSION"
echo "$branch" > "$BUILD_FROM_SOURCE_MARKER"
chown -R pulse:pulse "$INSTALL_DIR" 2>/dev/null || true
chown pulse:pulse "$BUILD_FROM_SOURCE_MARKER" 2>/dev/null || true
rm -f "$INSTALL_DIR/bin/pulse.old"
cd "$original_dir" >/dev/null 2>&1 || true
rm -rf "$temp_build"
SKIP_DOWNLOAD=true
print_success "Successfully built and installed Pulse from source (branch: $branch)"
return 0
}
setup_directories() {
print_info "Setting up directories..."
@ -1950,8 +2036,23 @@ setup_update_command() {
set -e
INSTALL_ROOT="/opt/pulse"
MARKER_FILE="${INSTALL_ROOT}/BUILD_FROM_SOURCE"
extra_args=()
if [[ -f "$MARKER_FILE" ]]; then
branch=$(tr -d '\r\n' <"$MARKER_FILE" 2>/dev/null || true)
if [[ -n "$branch" ]]; then
extra_args+=(--source "$branch")
fi
fi
echo "Updating Pulse..."
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash
if [[ ${#extra_args[@]} -gt 0 ]]; then
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash -s -- "${extra_args[@]}"
else
curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash
fi
echo ""
echo "Update complete! Pulse will restart automatically."
@ -2224,172 +2325,22 @@ main() {
if check_existing_installation; then
# If building from source was requested, skip the update prompt
if [[ "$BUILD_FROM_SOURCE" == "true" ]]; then
print_info "Building Pulse from source (branch: $SOURCE_BRANCH)..."
# Install build dependencies
print_info "Installing build dependencies..."
if ! (apt-get update >/dev/null 2>&1 && apt-get install -y git make nodejs npm wget >/dev/null 2>&1); then
print_error "Failed to install build dependencies"
exit 1
fi
# Check for Go installation
GO_INSTALLED=false
if ! command -v go &> /dev/null; then
print_info "Go is not installed. Installing Go 1.24..."
else
GO_VERSION=$(go version | grep -oP 'go\K[0-9]+\.[0-9]+')
if awk "BEGIN {exit !($GO_VERSION < 1.24)}"; then
print_info "Go version $GO_VERSION is too old. Installing Go 1.24..."
else
print_info "Go version $GO_VERSION is installed"
GO_INSTALLED=true
fi
fi
if [[ "$GO_INSTALLED" != "true" ]]; then
# Detect architecture for Go download
ARCH=$(uname -m)
case $ARCH in
x86_64)
GO_ARCH="amd64"
;;
aarch64)
GO_ARCH="arm64"
;;
armv7l)
GO_ARCH="armv6l"
;;
*)
print_error "Unsupported architecture: $ARCH"
exit 1
;;
esac
cd /tmp
wget -q "https://go.dev/dl/go1.24.7.linux-${GO_ARCH}.tar.gz"
rm -rf /usr/local/go
tar -C /usr/local -xzf "go1.24.7.linux-${GO_ARCH}.tar.gz"
export PATH=/usr/local/go/bin:$PATH
rm "go1.24.7.linux-${GO_ARCH}.tar.gz"
fi
# Clone and build
print_info "Cloning repository..."
TEMP_BUILD_DIR=$(mktemp -d)
cd "$TEMP_BUILD_DIR"
if ! git clone -b "$SOURCE_BRANCH" "https://github.com/$GITHUB_REPO.git" pulse-src >/dev/null 2>&1; then
print_error "Failed to clone repository"
rm -rf "$TEMP_BUILD_DIR"
exit 1
fi
cd pulse-src
print_info "Installing frontend dependencies..."
cd frontend-modern
if ! npm install >/dev/null 2>&1; then
print_error "Failed to install frontend dependencies"
cd /
rm -rf "$TEMP_BUILD_DIR"
exit 1
fi
cd ..
print_info "Building Pulse..."
# Ensure Go is in PATH for the build
export PATH=/usr/local/go/bin:$PATH
if ! make build >/dev/null 2>&1; then
print_error "Build failed"
cd /
rm -rf "$TEMP_BUILD_DIR"
exit 1
fi
# Detect service name before stopping
SERVICE_NAME=$(detect_service_name)
# Stop existing service if running
if systemctl is-active --quiet $SERVICE_NAME 2>/dev/null; then
print_info "Stopping existing Pulse service..."
systemctl stop $SERVICE_NAME
fi
# Install the built binary
print_info "Installing Pulse..."
create_user
setup_directories
# Copy the built binary (Makefile builds to ./pulse not bin/pulse)
cp pulse "$INSTALL_DIR/bin/pulse"
chmod +x "$INSTALL_DIR/bin/pulse"
chown pulse:pulse "$INSTALL_DIR/bin/pulse"
print_info "Building Docker agent from source..."
agent_version=$(git describe --tags --always --dirty 2>/dev/null || echo "dev")
if ! go build -ldflags="-X github.com/rcourtman/pulse-go-rewrite/internal/dockeragent.Version=${agent_version}" -o pulse-docker-agent ./cmd/pulse-docker-agent >/dev/null 2>&1; then
print_error "Failed to build Docker agent binary"
cd /
rm -rf "$TEMP_BUILD_DIR"
if ! build_from_source "$SOURCE_BRANCH"; then
exit 1
fi
cp -f pulse-docker-agent "$INSTALL_DIR/pulse-docker-agent"
cp -f pulse-docker-agent "$INSTALL_DIR/bin/pulse-docker-agent"
chmod +x "$INSTALL_DIR/pulse-docker-agent" "$INSTALL_DIR/bin/pulse-docker-agent"
chown pulse:pulse "$INSTALL_DIR/pulse-docker-agent" "$INSTALL_DIR/bin/pulse-docker-agent"
ln -sf "$INSTALL_DIR/bin/pulse-docker-agent" /usr/local/bin/pulse-docker-agent
rm -f pulse-docker-agent
print_info "Building temperature proxy from source..."
if ! go build -o pulse-sensor-proxy ./cmd/pulse-sensor-proxy >/dev/null 2>&1; then
print_error "Failed to build temperature proxy binary"
cd /
rm -rf "$TEMP_BUILD_DIR"
exit 1
fi
cp -f pulse-sensor-proxy "$INSTALL_DIR/bin/pulse-sensor-proxy"
chmod +x "$INSTALL_DIR/bin/pulse-sensor-proxy"
chown pulse:pulse "$INSTALL_DIR/bin/pulse-sensor-proxy"
rm -f pulse-sensor-proxy
ln -sf "$INSTALL_DIR/bin/pulse" /usr/local/bin/pulse
mkdir -p "$INSTALL_DIR/scripts"
if [[ -f "scripts/install-docker-agent.sh" ]]; then
cp "scripts/install-docker-agent.sh" "$INSTALL_DIR/scripts/install-docker-agent.sh"
chmod 755 "$INSTALL_DIR/scripts/install-docker-agent.sh"
chown pulse:pulse "$INSTALL_DIR/scripts/install-docker-agent.sh"
else
print_warn "Docker agent install script missing from source checkout; skipping installation"
fi
if [[ -f "scripts/install-docker.sh" ]]; then
cp "scripts/install-docker.sh" "$INSTALL_DIR/scripts/install-docker.sh"
chmod 755 "$INSTALL_DIR/scripts/install-docker.sh"
chown pulse:pulse "$INSTALL_DIR/scripts/install-docker.sh"
fi
if [[ -f "scripts/install-sensor-proxy.sh" ]]; then
cp "scripts/install-sensor-proxy.sh" "$INSTALL_DIR/scripts/install-sensor-proxy.sh"
chmod 755 "$INSTALL_DIR/scripts/install-sensor-proxy.sh"
chown pulse:pulse "$INSTALL_DIR/scripts/install-sensor-proxy.sh"
fi
build_agent_binaries_from_source "$agent_version"
# Setup update command and service
setup_update_command
install_systemd_service
if [[ "$ENABLE_AUTO_UPDATES" == "true" ]]; then
setup_auto_updates
fi
start_pulse
create_marker_file
# Clean up
cd /
rm -rf "$TEMP_BUILD_DIR"
print_completion
exit 0
fi
@ -2970,7 +2921,7 @@ while [[ $# -gt 0 ]]; do
fi
shift 2
;;
--main|--source|--from-source|--branch)
--source|--from-source|--branch)
BUILD_FROM_SOURCE=true
# Optional: specify branch
if [[ $# -gt 1 ]] && [[ -n "$2" ]] && [[ ! "$2" =~ ^-- ]]; then
@ -2988,7 +2939,6 @@ while [[ $# -gt 0 ]]; do
echo " --rc, --pre Install latest RC/pre-release version"
echo " --stable Install latest stable version (default)"
echo " --version VERSION Install specific version (e.g., v4.4.0-rc.1)"
echo " --main Build and install from main branch source"
echo " --source [BRANCH] Build and install from source (default: main)"
echo " --enable-auto-updates Enable automatic stable updates (via systemd timer)"
echo " --proxy MODE Control temperature proxy installation (yes/no/auto)"

View file

@ -168,8 +168,18 @@ perform_update() {
log info "Downloading and installing update"
# Run install script with specific version
local marker_file="$INSTALL_DIR/BUILD_FROM_SOURCE"
local -a installer_args=(--version "$new_version")
if [[ -f "$marker_file" ]]; then
local branch
branch=$(tr -d '\r\n' <"$marker_file" 2>/dev/null || true)
if [[ -n "$branch" ]]; then
installer_args=(--source "$branch" "${installer_args[@]}")
fi
fi
if curl -sSL "https://raw.githubusercontent.com/$GITHUB_REPO/main/install.sh" | \
bash -s -- --version "$new_version" 2>&1 | \
bash -s -- "${installer_args[@]}" 2>&1 | \
while IFS= read -r line; do
log info "installer: $line"
done; then
@ -292,4 +302,4 @@ main() {
}
# Run main function
main "$@"
main "$@"