mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 09:28:14 +00:00
feat: Linux packaging, SDK v0.7.1, fix rawmode conflict
- go.mod: SDK pseudo-version -> v0.7.1 (remote tag), go.sum updated - cmd/waiter/rawmode_linux.go: remove (conflicts with raw_unix.go) - cmd/gui/package.json: add rpm/AppImage Linux targets - package/package-linux.sh: cross-distro packaging script (deb/tar.gz/rpm) - package/linux/: DEBIAN control files, postinst/prerm, RPM spec
This commit is contained in:
@ -22,7 +22,9 @@
|
||||
"productName": "HomeAgent",
|
||||
"linux": {
|
||||
"target": [
|
||||
"deb"
|
||||
"deb",
|
||||
"rpm",
|
||||
"AppImage"
|
||||
],
|
||||
"category": "Utility",
|
||||
"icon": "icon.svg"
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
//go:build linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setRawMode(fd int) (func(), error) {
|
||||
var old termios
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), TCGETS, uintptr(unsafe.Pointer(&old))); err != 0 {
|
||||
return func() {}, err
|
||||
}
|
||||
new := old
|
||||
new.Lflag &^= ICANON | ECHO | ISIG
|
||||
new.Cc[VMIN] = 1
|
||||
new.Cc[VTIME] = 0
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), TCSETS, uintptr(unsafe.Pointer(&new))); err != 0 {
|
||||
return func() {}, err
|
||||
}
|
||||
return func() {
|
||||
syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), TCSETS, uintptr(unsafe.Pointer(&old)))
|
||||
}, nil
|
||||
}
|
||||
2
go.mod
2
go.mod
@ -10,6 +10,6 @@ require (
|
||||
|
||||
require github.com/yanyiwu/gojieba v1.4.7
|
||||
|
||||
require gitcode.com/JianFeeeee/homeagent-sdk v0.0.0-20260708004841-e9bdcf9304b0 // direct
|
||||
require gitcode.com/JianFeeeee/homeagent-sdk v0.7.1
|
||||
|
||||
replace gitcode.com/JianFeeeee/homeagent-sdk => E:\program\homeagent\homeagentsdk
|
||||
|
||||
4
go.sum
4
go.sum
@ -1,5 +1,5 @@
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
gitcode.com/JianFeeeee/homeagent-sdk v0.7.1 h1:2XEtUgV200uOqbGGEiKT5QyBmZ5aIfNiwm/Ozrm9AOg=
|
||||
gitcode.com/JianFeeeee/homeagent-sdk v0.7.1/go.mod h1:G48Rgpw9ReTkCf0qBHf50jb5CSeNR2c4OWcgcEm0plo=
|
||||
github.com/mattn/go-sqlite3 v1.14.48 h1:7XHIgl0a8HwOaiK4E47ozLkST78rR9+OtNGx27D/TFs=
|
||||
github.com/mattn/go-sqlite3 v1.14.48/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
|
||||
github.com/yanyiwu/gojieba v1.4.7 h1:2YkXELcYLTE0SJetq6xv4MjpEikWga6VpFn4jIFFQ/k=
|
||||
|
||||
18
package/linux/deb/control-client
Normal file
18
package/linux/deb/control-client
Normal file
@ -0,0 +1,18 @@
|
||||
Package: homeagent-client
|
||||
Version: VERSION_PLACEHOLDER
|
||||
Architecture: ARCH_PLACEHOLDER
|
||||
Maintainer: HomeAgent Team <team@homeagent.ai>
|
||||
Installed-Size: INSTALLED_SIZE_PLACEHOLDER
|
||||
Depends: libc6 (>= 2.28)
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Homepage: https://github.com/trueagent/HomeAgent
|
||||
Description: HomeAgent Client (CLI + GUI, no daemon)
|
||||
HomeAgent is a personal AI home assistant that integrates
|
||||
large language models with system automation.
|
||||
.
|
||||
This package includes the client components:
|
||||
- waiter: command-line client
|
||||
- homeagent-gui: desktop graphical interface
|
||||
.
|
||||
This variant connects to a remote HomeAgent server.
|
||||
17
package/linux/deb/control-full
Normal file
17
package/linux/deb/control-full
Normal file
@ -0,0 +1,17 @@
|
||||
Package: homeagent-full
|
||||
Version: VERSION_PLACEHOLDER
|
||||
Architecture: ARCH_PLACEHOLDER
|
||||
Maintainer: HomeAgent Team <team@homeagent.ai>
|
||||
Installed-Size: INSTALLED_SIZE_PLACEHOLDER
|
||||
Depends: libc6 (>= 2.28)
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Homepage: https://github.com/trueagent/HomeAgent
|
||||
Description: HomeAgent Full Installation (Daemon + CLI + GUI)
|
||||
HomeAgent is a personal AI home assistant that integrates
|
||||
large language models with system automation.
|
||||
.
|
||||
This package includes the full suite:
|
||||
- homed: the core daemon (background service)
|
||||
- waiter: command-line client
|
||||
- homeagent-gui: desktop graphical interface
|
||||
16
package/linux/deb/control-server
Normal file
16
package/linux/deb/control-server
Normal file
@ -0,0 +1,16 @@
|
||||
Package: homeagent-server
|
||||
Version: VERSION_PLACEHOLDER
|
||||
Architecture: ARCH_PLACEHOLDER
|
||||
Maintainer: HomeAgent Team <team@homeagent.ai>
|
||||
Installed-Size: INSTALLED_SIZE_PLACEHOLDER
|
||||
Depends: libc6 (>= 2.28)
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Homepage: https://github.com/trueagent/HomeAgent
|
||||
Description: HomeAgent Server (Daemon + CLI, no GUI)
|
||||
HomeAgent is a personal AI home assistant that integrates
|
||||
large language models with system automation.
|
||||
.
|
||||
This package includes the server components:
|
||||
- homed: the core daemon (background service)
|
||||
- waiter: command-line client
|
||||
25
package/linux/deb/postinst
Executable file
25
package/linux/deb/postinst
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
SERVICE_NAME="homeagent"
|
||||
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||
HOMED_BIN="/usr/bin/homed"
|
||||
DATA_DIR="/var/lib/homeagent"
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
if [ -f "$HOMED_BIN" ]; then
|
||||
mkdir -p "$DATA_DIR"
|
||||
|
||||
if [ -f "$SERVICE_FILE" ]; then
|
||||
systemctl daemon-reload 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
19
package/linux/deb/prerm
Executable file
19
package/linux/deb/prerm
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
SERVICE_NAME="homeagent"
|
||||
|
||||
case "$1" in
|
||||
remove|deconfigure)
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl stop "$SERVICE_NAME" 2>/dev/null || true
|
||||
systemctl disable "$SERVICE_NAME" 2>/dev/null || true
|
||||
fi
|
||||
;;
|
||||
upgrade)
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
111
package/linux/homeagent.spec
Normal file
111
package/linux/homeagent.spec
Normal file
@ -0,0 +1,111 @@
|
||||
# HomeAgent RPM Spec
|
||||
# Build: rpmbuild -ba homeagent.spec
|
||||
#
|
||||
# Define variant at build time:
|
||||
# rpmbuild -ba --define "variant full" homeagent.spec
|
||||
# rpmbuild -ba --define "variant server" homeagent.spec
|
||||
# rpmbuild -ba --define "variant client" homeagent.spec
|
||||
|
||||
%define _prefix /usr
|
||||
%define _bindir %{_prefix}/bin
|
||||
%define _unitdir %{_prefix}/lib/systemd/system
|
||||
%define _datadir %{_prefix}/share/homeagent
|
||||
%define _varlibdir /var/lib/homeagent
|
||||
|
||||
%if %{undefined variant}
|
||||
%define variant full
|
||||
%endif
|
||||
|
||||
Name: homeagent-%{variant}
|
||||
Version: %{_version}
|
||||
Release: 1%{?dist}
|
||||
Summary: HomeAgent - Personal AI Home Assistant
|
||||
License: Proprietary
|
||||
URL: https://github.com/trueagent/HomeAgent
|
||||
Group: System Environment/Daemons
|
||||
BuildArch: %{_arch}
|
||||
|
||||
%if "%{variant}" == "full" || "%{variant}" == "server"
|
||||
Requires: systemd
|
||||
%endif
|
||||
%if "%{variant}" == "full"
|
||||
Requires: libX11, libxcb, libdrm, mesa-libGL, nss, nspr, atk, at-spi2-atk, cairo, cups-libs, pango, gtk3
|
||||
%endif
|
||||
%if "%{variant}" == "client"
|
||||
Requires: libX11, libxcb, libdrm, mesa-libGL, nss, nspr, atk, at-spi2-atk, cairo, cups-libs, pango, gtk3
|
||||
%endif
|
||||
|
||||
%description
|
||||
HomeAgent is a personal AI home assistant that integrates large language
|
||||
models with system automation.
|
||||
|
||||
%if "%{variant}" == "full"
|
||||
This package includes the full suite: homed (daemon), waiter (CLI),
|
||||
and homeagent-gui (desktop GUI).
|
||||
%else
|
||||
%if "%{variant}" == "server"
|
||||
This package includes the server components: homed (daemon) and waiter (CLI).
|
||||
%else
|
||||
%if "%{variant}" == "client"
|
||||
This package includes the client components: waiter (CLI) and
|
||||
homeagent-gui (desktop GUI). Connects to a remote HomeAgent server.
|
||||
%endif
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%install
|
||||
mkdir -p %{buildroot}%{_bindir}
|
||||
mkdir -p %{buildroot}%{_unitdir}
|
||||
mkdir -p %{buildroot}%{_varlibdir}
|
||||
|
||||
%if "%{variant}" == "full" || "%{variant}" == "server"
|
||||
install -m 755 %{_sourcedir}/homed %{buildroot}%{_bindir}/homed
|
||||
install -m 644 %{_sourcedir}/homeagent.service %{buildroot}%{_unitdir}/homeagent.service
|
||||
%endif
|
||||
|
||||
%if "%{variant}" == "full" || "%{variant}" == "client"
|
||||
install -m 755 %{_sourcedir}/waiter %{buildroot}%{_bindir}/waiter
|
||||
%endif
|
||||
|
||||
%if "%{variant}" == "full" || "%{variant}" == "client"
|
||||
mkdir -p %{buildroot}%{_datadir}/homeagent-gui
|
||||
cp -r %{_sourcedir}/homeagent-gui-linux-*/* %{buildroot}%{_datadir}/homeagent-gui/
|
||||
%endif
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
%if "%{variant}" == "full" || "%{variant}" == "server"
|
||||
%{_bindir}/homed
|
||||
%{_unitdir}/homeagent.service
|
||||
%dir %{_varlibdir}
|
||||
%endif
|
||||
|
||||
%if "%{variant}" == "full" || "%{variant}" == "client"
|
||||
%{_bindir}/waiter
|
||||
%endif
|
||||
|
||||
%if "%{variant}" == "full" || "%{variant}" == "client"
|
||||
%dir %{_datadir}/homeagent-gui
|
||||
%{_datadir}/homeagent-gui/*
|
||||
%endif
|
||||
|
||||
%post
|
||||
%if "%{variant}" == "full" || "%{variant}" == "server"
|
||||
mkdir -p %{_varlibdir}
|
||||
%systemd_post homeagent.service
|
||||
%endif
|
||||
|
||||
%preun
|
||||
%if "%{variant}" == "full" || "%{variant}" == "server"
|
||||
%systemd_preun homeagent.service
|
||||
%endif
|
||||
|
||||
%postun
|
||||
%if "%{variant}" == "full" || "%{variant}" == "server"
|
||||
%systemd_postun_with_restart homeagent.service
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Jul 20 2026 HomeAgent Team <team@homeagent.ai> - %{version}-1
|
||||
- Initial Linux packaging
|
||||
376
package/package-linux.sh
Executable file
376
package/package-linux.sh
Executable file
@ -0,0 +1,376 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
BUILD_DIR="${PROJECT_ROOT}/build"
|
||||
DIST_DIR="${PROJECT_ROOT}/dist/linux"
|
||||
VERSION="${VERSION:-$(git -C "$PROJECT_ROOT" describe --tags --dirty 2>/dev/null || echo "0.7.1")}"
|
||||
PACKAGE_ROOT="${PROJECT_ROOT}/package/linux"
|
||||
GO="${GO:-$(command -v go 2>/dev/null || echo "/home/jianf/go1.26.5/go/bin/go")}"
|
||||
|
||||
ARCH="${1:-amd64}" # amd64 or arm64
|
||||
ACTION="${2:-all}" # all, build, deb, tar, rpm
|
||||
|
||||
DEB_ARCH="$ARCH"
|
||||
RPM_ARCH="$ARCH"
|
||||
TAR_ARCH="$ARCH"
|
||||
case "$ARCH" in
|
||||
amd64) DEB_ARCH="amd64"; RPM_ARCH="x86_64"; TAR_ARCH="amd64" ;;
|
||||
arm64) DEB_ARCH="arm64"; RPM_ARCH="aarch64"; TAR_ARCH="arm64" ;;
|
||||
*) echo "Unknown arch: $ARCH (use amd64 or arm64)"; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "=== HomeAgent Linux Packager ==="
|
||||
echo "Version: $VERSION"
|
||||
echo "Arch: $ARCH"
|
||||
echo ""
|
||||
|
||||
# ---- prepare go.mod for Linux build: replace Windows SDK path with local clone ----
|
||||
prepare_gomod() {
|
||||
local gomod="$PROJECT_ROOT/go.mod"
|
||||
local sdk_clone="/tmp/homeagent-sdk"
|
||||
local patched=0
|
||||
|
||||
if grep -q 'replace gitcode.com/JianFeeeee/homeagent-sdk' "$gomod"; then
|
||||
echo ">>> Updating go.mod: replacing Windows SDK path with local clone..."
|
||||
if [ ! -d "$sdk_clone" ]; then
|
||||
echo ">>> Cloning SDK to $sdk_clone..."
|
||||
git clone git@gitcode.com:JianFeeeee/homeagent-sdk.git "$sdk_clone" 2>/dev/null || \
|
||||
git clone https://gitcode.com/JianFeeeee/homeagent-sdk.git "$sdk_clone" 2>/dev/null || true
|
||||
fi
|
||||
if [ -d "$sdk_clone" ]; then
|
||||
sed -i.bak "s|^replace gitcode.com/JianFeeeee/homeagent-sdk => .*|replace gitcode.com/JianFeeeee/homeagent-sdk => ${sdk_clone}|" "$gomod"
|
||||
patched=1
|
||||
else
|
||||
echo "WARNING: Cannot clone SDK. Build may fail."
|
||||
fi
|
||||
fi
|
||||
return $patched
|
||||
}
|
||||
|
||||
restore_gomod() {
|
||||
if [ -f "$PROJECT_ROOT/go.mod.bak" ]; then
|
||||
echo ">>> Restoring original go.mod..."
|
||||
mv "$PROJECT_ROOT/go.mod.bak" "$PROJECT_ROOT/go.mod"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---- temporarily move .syso files (Windows COFF objects) for Linux builds ----
|
||||
hide_syso() {
|
||||
echo ">>> Hiding .syso files (Windows-only object files)..."
|
||||
for dir in homed waiter; do
|
||||
if [ -f "$PROJECT_ROOT/cmd/$dir/$dir.syso" ]; then
|
||||
mv "$PROJECT_ROOT/cmd/$dir/$dir.syso" "$PROJECT_ROOT/cmd/$dir/$dir.syso.bak"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
restore_syso() {
|
||||
for dir in homed waiter; do
|
||||
if [ -f "$PROJECT_ROOT/cmd/$dir/$dir.syso.bak" ]; then
|
||||
mv "$PROJECT_ROOT/cmd/$dir/$dir.syso.bak" "$PROJECT_ROOT/cmd/$dir/$dir.syso"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# ensure both are always restored on exit
|
||||
restore_all() { restore_gomod; restore_syso; }
|
||||
trap restore_all EXIT
|
||||
|
||||
# ---- build Go binaries via existing build.sh ----
|
||||
build_go() {
|
||||
echo ">>> Building Go binaries for linux/$ARCH..."
|
||||
|
||||
prepare_gomod || true
|
||||
hide_syso
|
||||
|
||||
bash "$PROJECT_ROOT/package/build.sh" "linux/$ARCH" "homed" 2>&1 || {
|
||||
echo "WARNING: homed build failed (CGO/sqlite3 issue). Server/full packages may be incomplete."
|
||||
}
|
||||
bash "$PROJECT_ROOT/package/build.sh" "linux/$ARCH" "waiter" 2>&1 || {
|
||||
echo "WARNING: waiter build failed."
|
||||
}
|
||||
|
||||
local suffix="linux_${ARCH}"
|
||||
local homed_bin="$BUILD_DIR/homed_$suffix"
|
||||
local waiter_bin="$BUILD_DIR/waiter_$suffix"
|
||||
|
||||
if [ ! -f "$homed_bin" ]; then
|
||||
echo "ERROR: homed binary not found at $homed_bin"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "$waiter_bin" ]; then
|
||||
echo "ERROR: waiter binary not found at $waiter_bin"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo " homed: $homed_bin ($(du -h "$homed_bin" | cut -f1))"
|
||||
echo " waiter: $waiter_bin ($(du -h "$waiter_bin" | cut -f1))"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ---- build GUI (manual directory assembly, avoids electron-packager network issues) ----
|
||||
build_gui() {
|
||||
local gui_dir="$PROJECT_ROOT/cmd/gui"
|
||||
local gui_out="$BUILD_DIR/homeagent-gui-linux-${TAR_ARCH}"
|
||||
|
||||
if [ -d "$gui_out" ]; then
|
||||
echo ">>> GUI already built at $gui_out (delete to rebuild)"
|
||||
return
|
||||
fi
|
||||
|
||||
echo ">>> Building GUI directory for linux/$ARCH..."
|
||||
|
||||
if [ ! -d "$gui_dir/node_modules" ]; then
|
||||
echo " npm install..."
|
||||
(cd "$gui_dir" && npm install --production)
|
||||
fi
|
||||
|
||||
local electron_dir="$gui_dir/node_modules/electron/dist"
|
||||
if [ ! -f "$electron_dir/electron" ]; then
|
||||
echo " WARNING: electron binary not found at $electron_dir. GUI will be skipped."
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "$gui_out/resources/app/node_modules"
|
||||
mkdir -p "$gui_out/resources/app/renderer"
|
||||
|
||||
# copy electron runtime (binary + shared libs)
|
||||
cp -r "$electron_dir"/* "$gui_out/" 2>/dev/null
|
||||
rm -f "$gui_out/resources/default_app.asar" 2>/dev/null
|
||||
|
||||
# copy app source
|
||||
cp "$gui_dir/main.js" "$gui_out/resources/app/"
|
||||
cp "$gui_dir/preload.js" "$gui_out/resources/app/"
|
||||
cp "$gui_dir/package.json" "$gui_out/resources/app/"
|
||||
cp "$gui_dir/renderer/index.html" "$gui_out/resources/app/renderer/"
|
||||
cp "$gui_dir/renderer/app.js" "$gui_out/resources/app/renderer/"
|
||||
cp "$gui_dir/renderer/style.css" "$gui_out/resources/app/renderer/" 2>/dev/null || true
|
||||
cp "$gui_dir/renderer/mascot.svg" "$gui_out/resources/app/renderer/" 2>/dev/null || true
|
||||
|
||||
# production node_modules for app
|
||||
if [ -d "$gui_dir/node_modules" ]; then
|
||||
for mod in icojs; do
|
||||
if [ -d "$gui_dir/node_modules/$mod" ]; then
|
||||
cp -r "$gui_dir/node_modules/$mod" "$gui_out/resources/app/node_modules/"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# create desktop entry and symlink
|
||||
cat > "$gui_out/resources/app/homeagent-gui.desktop" << DESKTOP
|
||||
[Desktop Entry]
|
||||
Name=HomeAgent
|
||||
Comment=HomeAgent Desktop GUI
|
||||
Exec=$gui_out/homeagent-gui
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;
|
||||
Icon=$gui_out/resources/app/icon.svg
|
||||
DESKTOP
|
||||
|
||||
# create launcher script
|
||||
cat > "$gui_out/homeagent-gui" << 'LAUNCHER'
|
||||
#!/bin/sh
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec "$DIR/electron" "$DIR/resources/app" "$@"
|
||||
LAUNCHER
|
||||
chmod +x "$gui_out/homeagent-gui"
|
||||
chmod +x "$gui_out/electron"
|
||||
|
||||
echo " GUI built: $gui_out ($(du -sh "$gui_out" | cut -f1))"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ---- stage files for a variant ----
|
||||
stage_variant() {
|
||||
local variant="$1"
|
||||
local staging="$2"
|
||||
local suffix="linux_${ARCH}"
|
||||
|
||||
echo ">>> Staging $variant..."
|
||||
|
||||
mkdir -p "$staging/usr/bin"
|
||||
mkdir -p "$staging/etc/systemd/system"
|
||||
mkdir -p "$staging/var/lib/homeagent"
|
||||
|
||||
case "$variant" in
|
||||
full)
|
||||
cp "$BUILD_DIR/homed_$suffix" "$staging/usr/bin/homed"
|
||||
cp "$BUILD_DIR/waiter_$suffix" "$staging/usr/bin/waiter"
|
||||
cp "$PROJECT_ROOT/deploy/homeagent.service" "$staging/etc/systemd/system/homeagent.service"
|
||||
stage_gui "$staging"
|
||||
;;
|
||||
server)
|
||||
cp "$BUILD_DIR/homed_$suffix" "$staging/usr/bin/homed"
|
||||
cp "$BUILD_DIR/waiter_$suffix" "$staging/usr/bin/waiter"
|
||||
cp "$PROJECT_ROOT/deploy/homeagent.service" "$staging/etc/systemd/system/homeagent.service"
|
||||
;;
|
||||
client)
|
||||
cp "$BUILD_DIR/waiter_$suffix" "$staging/usr/bin/waiter"
|
||||
stage_gui "$staging"
|
||||
;;
|
||||
esac
|
||||
|
||||
chmod 755 "$staging/usr/bin/"* 2>/dev/null || true
|
||||
echo " OK"
|
||||
}
|
||||
|
||||
stage_gui() {
|
||||
local staging="$1"
|
||||
local gui_src="$BUILD_DIR/homeagent-gui-linux-${TAR_ARCH}"
|
||||
if [ -d "$gui_src" ]; then
|
||||
mkdir -p "$staging/usr/lib/homeagent-gui"
|
||||
cp -r "$gui_src"/* "$staging/usr/lib/homeagent-gui/"
|
||||
cat > "$staging/usr/bin/homeagent-gui" << 'SCRIPT'
|
||||
#!/bin/sh
|
||||
exec /usr/lib/homeagent-gui/homeagent-gui "$@"
|
||||
SCRIPT
|
||||
chmod 755 "$staging/usr/bin/homeagent-gui"
|
||||
else
|
||||
echo " WARNING: GUI not built, skipping GUI staging"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---- create .deb ----
|
||||
build_deb() {
|
||||
local variant="$1"
|
||||
local staging="$2"
|
||||
local deb_dir="${DIST_DIR}/deb"
|
||||
mkdir -p "$deb_dir"
|
||||
|
||||
local pkg_name="homeagent-${variant}_${VERSION}_${DEB_ARCH}.deb"
|
||||
local deb_root
|
||||
deb_root="$(mktemp -d)"
|
||||
|
||||
mkdir -p "$deb_root/DEBIAN"
|
||||
|
||||
local control_file="$PACKAGE_ROOT/deb/control-${variant}"
|
||||
local installed_size_kb
|
||||
installed_size_kb=$(du -sk "$staging" | cut -f1)
|
||||
|
||||
sed -e "s/VERSION_PLACEHOLDER/$VERSION/g" \
|
||||
-e "s/ARCH_PLACEHOLDER/$DEB_ARCH/g" \
|
||||
-e "s/INSTALLED_SIZE_PLACEHOLDER/$installed_size_kb/g" \
|
||||
"$control_file" > "$deb_root/DEBIAN/control"
|
||||
|
||||
if [ -f "$PACKAGE_ROOT/deb/postinst" ]; then
|
||||
cp "$PACKAGE_ROOT/deb/postinst" "$deb_root/DEBIAN/postinst"
|
||||
chmod 755 "$deb_root/DEBIAN/postinst"
|
||||
fi
|
||||
|
||||
if [ -f "$PACKAGE_ROOT/deb/prerm" ]; then
|
||||
cp "$PACKAGE_ROOT/deb/prerm" "$deb_root/DEBIAN/prerm"
|
||||
chmod 755 "$deb_root/DEBIAN/prerm"
|
||||
fi
|
||||
|
||||
cp -r "$staging"/* "$deb_root/" 2>/dev/null || true
|
||||
|
||||
echo ">>> Building .deb: $pkg_name"
|
||||
fakeroot dpkg-deb --build "$deb_root" "$deb_dir/$pkg_name" 2>/dev/null || \
|
||||
dpkg-deb --build "$deb_root" "$deb_dir/$pkg_name" 2>&1
|
||||
rm -rf "$deb_root"
|
||||
echo " Created: $deb_dir/$pkg_name ($(du -h "$deb_dir/$pkg_name" | cut -f1))"
|
||||
}
|
||||
|
||||
# ---- create .tar.gz ----
|
||||
build_tar() {
|
||||
local variant="$1"
|
||||
local staging="$2"
|
||||
local tar_dir="${DIST_DIR}/tar"
|
||||
mkdir -p "$tar_dir"
|
||||
|
||||
local archive_name="homeagent-${variant}_${VERSION}_linux_${TAR_ARCH}.tar.gz"
|
||||
local archive_dir="homeagent-${variant}"
|
||||
|
||||
echo ">>> Building .tar.gz: $archive_name"
|
||||
(cd "$staging" && tar czf "$tar_dir/$archive_name" --transform "s|^\.|${archive_dir}|" .)
|
||||
echo " Created: $tar_dir/$archive_name ($(du -h "$tar_dir/$archive_name" | cut -f1))"
|
||||
}
|
||||
|
||||
# ---- create .rpm (via fpm if available) ----
|
||||
build_rpm() {
|
||||
local variant="$1"
|
||||
local staging="$2"
|
||||
local rpm_dir="${DIST_DIR}/rpm"
|
||||
mkdir -p "$rpm_dir"
|
||||
|
||||
local pkg_name="homeagent-${variant}-${VERSION}-1.${RPM_ARCH}.rpm"
|
||||
|
||||
if command -v fpm &>/dev/null; then
|
||||
echo ">>> Building .rpm via fpm: $pkg_name"
|
||||
fpm -s dir -t rpm \
|
||||
-n "homeagent-${variant}" \
|
||||
-v "$VERSION" \
|
||||
--iteration 1 \
|
||||
-a "$RPM_ARCH" \
|
||||
--description "HomeAgent ${variant^} package" \
|
||||
--url "https://github.com/trueagent/HomeAgent" \
|
||||
--license "Proprietary" \
|
||||
-C "$staging" \
|
||||
-p "$rpm_dir/$pkg_name" \
|
||||
.
|
||||
echo " Created: $rpm_dir/$pkg_name"
|
||||
else
|
||||
echo " SKIP .rpm: fpm not installed. Install it with: gem install fpm"
|
||||
echo " Alternatively, build RPM on Fedora/RHEL using:"
|
||||
echo " rpmbuild -ba package/linux/homeagent.spec"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---- main ----
|
||||
main() {
|
||||
local target_arch="$ARCH"
|
||||
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
case "$ACTION" in
|
||||
all|build)
|
||||
build_go
|
||||
build_gui
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$ACTION" = "build" ]; then
|
||||
echo ""
|
||||
echo "=== Build complete. Binaries in $BUILD_DIR ==="
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "$DIST_DIR"
|
||||
|
||||
for variant in full server client; do
|
||||
echo ""
|
||||
echo "=============================================="
|
||||
echo " Packaging: $variant"
|
||||
echo "=============================================="
|
||||
|
||||
local staging
|
||||
staging=$(mktemp -d)
|
||||
stage_variant "$variant" "$staging"
|
||||
|
||||
case "$ACTION" in
|
||||
all|deb) build_deb "$variant" "$staging" ;;
|
||||
esac
|
||||
|
||||
case "$ACTION" in
|
||||
all|tar) build_tar "$variant" "$staging" ;;
|
||||
esac
|
||||
|
||||
case "$ACTION" in
|
||||
all|rpm) build_rpm "$variant" "$staging" ;;
|
||||
esac
|
||||
|
||||
rm -rf "$staging"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Done! Packages in: $DIST_DIR ==="
|
||||
echo ""
|
||||
echo "Summary:"
|
||||
find "$DIST_DIR" -type f -name "*.deb" -o -name "*.tar.gz" -o -name "*.rpm" 2>/dev/null | sort | while read -r f; do
|
||||
echo " $(du -h "$f" | cut -f1) $f"
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
Reference in New Issue
Block a user