Add (beta) support for Fleet Desktop to linux (#5221)
* Add (beta) support for Fleet Desktop to linux * Add dependency for linux desktop * Amend makefile uname check * Clarify env vars used for linux in execuser * Add final set of fixes * Remove -it from docker run * Add desktop to the update runner for Linux * Re-arrange tag.gz and fix upgrade check for linux desktop
This commit is contained in:
@@ -63,7 +63,7 @@ jobs:
|
||||
path: desktop.app.tar.gz
|
||||
|
||||
desktop-windows:
|
||||
runs-on: macos-latest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Install Go
|
||||
@@ -83,4 +83,27 @@ jobs:
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v2
|
||||
with:
|
||||
name: fleet-desktop.exe
|
||||
path: fleet-desktop.exe
|
||||
path: fleet-desktop.exe
|
||||
|
||||
desktop-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab # v2
|
||||
with:
|
||||
go-version: '^1.17.0'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 # v2
|
||||
|
||||
- name: Generate desktop.tar.gz
|
||||
run: |
|
||||
FLEET_DESKTOP_VERSION=$FLEET_DESKTOP_VERSION \
|
||||
make desktop-linux
|
||||
|
||||
- name: Upload desktop.tar.gz
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v2
|
||||
with:
|
||||
name: desktop.tar.gz
|
||||
path: desktop.tar.gz
|
||||
@@ -60,6 +60,7 @@ terraform.tfstate*
|
||||
# generated installers
|
||||
fleet-osquery*
|
||||
desktop.app.tar.gz
|
||||
desktop.tar.gz
|
||||
|
||||
# residual files when running the cpe command
|
||||
cmd/cpe/etagenv
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM golang:1.17.8-bullseye
|
||||
LABEL maintainer="Fleet Developers <hello@fleetdm.com>"
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
libgtk-3-dev \
|
||||
libayatana-appindicator3-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN mkdir -p /usr/src/fleet
|
||||
RUN mkdir -p /output
|
||||
|
||||
WORKDIR /usr/src/fleet
|
||||
|
||||
COPY orbit ./orbit
|
||||
COPY pkg ./pkg
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
CMD /bin/bash
|
||||
@@ -175,6 +175,10 @@ deps-js:
|
||||
|
||||
deps-go:
|
||||
go mod download
|
||||
ifeq ($(shell uname -s),Linux)
|
||||
# Dependency required for Linux Fleet Desktop.
|
||||
sudo apt-get install gcc libgtk-3-dev libayatana-appindicator3-dev -y
|
||||
endif
|
||||
|
||||
migration:
|
||||
go run github.com/fleetdm/goose/cmd/goose -dir server/datastore/mysql/migrations/tables create $(name)
|
||||
@@ -306,6 +310,8 @@ endif
|
||||
#
|
||||
# Usage:
|
||||
# FLEET_DESKTOP_APPLE_AUTHORITY=foo FLEET_DESKTOP_VERSION=0.0.1 make desktop-app-tar-gz
|
||||
#
|
||||
# Output: desktop.app.tar.gz
|
||||
desktop-app-tar-gz:
|
||||
ifneq ($(shell uname), Darwin)
|
||||
@echo "Makefile target desktop-app-tar-gz is only supported on macOS"
|
||||
@@ -313,12 +319,37 @@ ifneq ($(shell uname), Darwin)
|
||||
endif
|
||||
go run ./tools/desktop macos
|
||||
|
||||
FLEET_DESKTOP_VERSION ?= unknown
|
||||
|
||||
# Build desktop executable for Windows.
|
||||
#
|
||||
# Usage:
|
||||
# FLEET_DESKTOP_VERSION=0.0.1 make desktop-windows
|
||||
#
|
||||
# Output: fleet-desktop.exe
|
||||
desktop-windows:
|
||||
GOOS=windows GOARCH=amd64 go build -ldflags "-H=windowsgui" -o fleet-desktop.exe ./orbit/cmd/desktop
|
||||
GOOS=windows GOARCH=amd64 go build -ldflags "-H=windowsgui -X=main.version=$(FLEET_DESKTOP_VERSION)" -o fleet-desktop.exe ./orbit/cmd/desktop
|
||||
|
||||
# Build desktop executable for Linux.
|
||||
#
|
||||
# Usage:
|
||||
# FLEET_DESKTOP_VERSION=0.0.1 make desktop-linux
|
||||
#
|
||||
# Output: desktop.tar.gz
|
||||
desktop-linux:
|
||||
docker build -f Dockerfile-desktop-linux -t desktop-linux-builder .
|
||||
docker run --rm -v $(shell pwd):/output desktop-linux-builder /bin/bash -c "\
|
||||
mkdir /output/fleet-desktop && \
|
||||
go build -o /output/fleet-desktop/fleet-desktop -ldflags "-X=main.version=$(FLEET_DESKTOP_VERSION)" /usr/src/fleet/orbit/cmd/desktop && \
|
||||
cp /usr/lib/x86_64-linux-gnu/libayatana-appindicator3.so.1 \
|
||||
/usr/lib/x86_64-linux-gnu/libayatana-ido3-0.4.so.0 \
|
||||
/usr/lib/x86_64-linux-gnu/libayatana-indicator3.so.7 \
|
||||
/lib/x86_64-linux-gnu/libm.so.6 \
|
||||
/usr/lib/x86_64-linux-gnu/libdbusmenu-gtk3.so.4 \
|
||||
/usr/lib/x86_64-linux-gnu/libdbusmenu-glib.so.4 \
|
||||
/output/fleet-desktop && cd /output && \
|
||||
tar czf desktop.tar.gz fleet-desktop && \
|
||||
rm -r fleet-desktop"
|
||||
|
||||
# db-replica-setup setups one main and one read replica MySQL instance for dev/testing.
|
||||
# - Assumes the docker containers are already running (tools/mysql-replica-testing/docker-compose.yml)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
* Add (beta) support for Fleet Desktop to linux.
|
||||
@@ -251,6 +251,9 @@ func updatesAddFunc(c *cli.Context) error {
|
||||
case name == "desktop" && platform == "windows":
|
||||
// This is a special case for the desktop target on Windows.
|
||||
dstPath = filepath.Join(filepath.Dir(dstPath), constant.DesktopAppExecName+".exe")
|
||||
case name == "desktop" && platform == "linux":
|
||||
// This is a special case for the desktop target on Linux.
|
||||
dstPath += ".tar.gz"
|
||||
case strings.HasSuffix(target, ".exe"):
|
||||
dstPath += ".exe"
|
||||
case strings.HasSuffix(target, ".app.tar.gz"):
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
//go:build darwin || windows
|
||||
// +build darwin windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -17,12 +14,15 @@ import (
|
||||
"github.com/getlantern/systray"
|
||||
)
|
||||
|
||||
var version = "unknown"
|
||||
|
||||
func main() {
|
||||
// Our TUF provided targets must support launching with "--help".
|
||||
if len(os.Args) > 1 && os.Args[1] == "--help" {
|
||||
fmt.Println("Fleet Desktop application executable")
|
||||
return
|
||||
}
|
||||
log.Printf("fleet-desktop version=%s\n", version)
|
||||
|
||||
devURL := os.Getenv("FLEET_DESKTOP_DEVICE_URL")
|
||||
if devURL == "" {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
// TODO(lucas): Once we support Linux, amend the above build tags.
|
||||
//go:build darwin || linux
|
||||
// +build darwin linux
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -229,6 +229,8 @@ func main() {
|
||||
opt.Targets["desktop"] = update.DesktopMacOSTarget
|
||||
case "windows":
|
||||
opt.Targets["desktop"] = update.DesktopWindowsTarget
|
||||
case "linux":
|
||||
opt.Targets["desktop"] = update.DesktopLinuxTarget
|
||||
default:
|
||||
log.Fatal().Str("GOOS", runtime.GOOS).Msg("unsupported GOOS for desktop target")
|
||||
}
|
||||
@@ -321,7 +323,7 @@ func main() {
|
||||
|
||||
if !c.Bool("disable-updates") {
|
||||
targets := []string{"orbit", "osqueryd"}
|
||||
if c.Bool("fleet-desktop") && (runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
|
||||
if c.Bool("fleet-desktop") {
|
||||
targets = append(targets, "desktop")
|
||||
}
|
||||
updateRunner, err := update.NewRunner(updater, update.RunnerOptions{
|
||||
@@ -483,7 +485,7 @@ func main() {
|
||||
}))
|
||||
g.Add(ext.Execute, ext.Interrupt)
|
||||
|
||||
if c.Bool("fleet-desktop") && (runtime.GOOS == "darwin" || runtime.GOOS == "windows") {
|
||||
if c.Bool("fleet-desktop") {
|
||||
desktopRunner := newDesktopRunner(desktopPath, fleetURL, deviceAuthToken, c.Bool("insecure"))
|
||||
g.Add(desktopRunner.actor())
|
||||
}
|
||||
@@ -557,7 +559,7 @@ func (d *desktopRunner) execute() error {
|
||||
|
||||
for {
|
||||
// First retry logic to start fleet-desktop.
|
||||
if done := retry(30*time.Second, d.interruptCh, func() bool {
|
||||
if done := retry(30*time.Second, false, d.interruptCh, func() bool {
|
||||
// Orbit runs as root user on Unix and as SYSTEM (Windows Service) user on Windows.
|
||||
// To be able to run the desktop application (mostly to register the icon in the system tray)
|
||||
// we need to run the application as the login user.
|
||||
@@ -572,7 +574,8 @@ func (d *desktopRunner) execute() error {
|
||||
}
|
||||
|
||||
// Second retry logic to monitor fleet-desktop.
|
||||
if done := retry(30*time.Second, d.interruptCh, func() bool {
|
||||
// Call with waitFirst=true to give some time for the process to start.
|
||||
if done := retry(30*time.Second, true, d.interruptCh, func() bool {
|
||||
switch _, err := getProcessByName(constant.DesktopAppExecName); {
|
||||
case err == nil:
|
||||
return true // all good, process is running, retry.
|
||||
@@ -589,14 +592,17 @@ func (d *desktopRunner) execute() error {
|
||||
}
|
||||
}
|
||||
|
||||
func retry(d time.Duration, done chan struct{}, fn func() bool) bool {
|
||||
func retry(d time.Duration, waitFirst bool, done chan struct{}, fn func() bool) bool {
|
||||
ticker := time.NewTicker(d)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
if retry := fn(); !retry {
|
||||
return false
|
||||
if !waitFirst {
|
||||
if retry := fn(); !retry {
|
||||
return false
|
||||
}
|
||||
}
|
||||
waitFirst = false
|
||||
select {
|
||||
case <-done:
|
||||
return true
|
||||
|
||||
@@ -1,5 +1,114 @@
|
||||
package execuser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// run uses sudo to run the given path as login user.
|
||||
func run(path string, opts eopts) error {
|
||||
panic("unimplemented")
|
||||
user, err := getLoginUID()
|
||||
if err != nil {
|
||||
return fmt.Errorf("get user: %w", err)
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Str("user", user.name).
|
||||
Int64("id", user.id).
|
||||
Msg("running sudo")
|
||||
|
||||
arg := []string{"-u", user.name, "-H"}
|
||||
for _, nv := range opts.env {
|
||||
arg = append(arg, fmt.Sprintf("%s=%s", nv[0], nv[1]))
|
||||
}
|
||||
arg = append(arg,
|
||||
// TODO(lucas): Default to display 0, revisit when working on
|
||||
// multi-user/multi-session support. This assumes there's only
|
||||
// one desktop session and belongs to the user returned in `getLoginUID'.
|
||||
"DISPLAY=:0",
|
||||
// DBUS_SESSION_BUS_ADDRESS sets the location of the user login session bus.
|
||||
// Required by the libayatana-appindicator3 library to display a tray icon
|
||||
// on the desktop session.
|
||||
fmt.Sprintf("DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%d/bus", user.id),
|
||||
fmt.Sprintf("LD_LIBRARY_PATH=%s:%s", filepath.Dir(path), os.ExpandEnv("$LD_LIBRARY_PATH")),
|
||||
path,
|
||||
)
|
||||
|
||||
cmd := exec.Command("sudo", arg...)
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
log.Printf("cmd=%s", cmd.String())
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return fmt.Errorf("open path %q: %w", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type user struct {
|
||||
name string
|
||||
id int64
|
||||
}
|
||||
|
||||
// getLoginUID returns the name and uid of the first login user
|
||||
// as reported by the `users' command.
|
||||
//
|
||||
// NOTE(lucas): It is always picking first login user as returned
|
||||
// by `users', revisit when working on multi-user/multi-session support.
|
||||
func getLoginUID() (*user, error) {
|
||||
out, err := exec.Command("users").CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("users exec failed: %w", err)
|
||||
}
|
||||
usernames := parseUsersOutput(string(out))
|
||||
username := usernames[0]
|
||||
if username == "" {
|
||||
return nil, fmt.Errorf("no user session found")
|
||||
}
|
||||
out, err = exec.Command("id", "-u", username).CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("id exec failed: %w", err)
|
||||
}
|
||||
uid, err := parseIDOutput(string(out))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user{
|
||||
name: username,
|
||||
id: uid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// parseUsersOutput parses the output of the `users' command.
|
||||
//
|
||||
// `users' command prints on a single line a blank-separated list of user names of
|
||||
// users currently logged in to the current host. Each user name
|
||||
// corresponds to a login session, so if a user has more than one login
|
||||
// session, that user's name will appear the same number of times in the
|
||||
// output.
|
||||
//
|
||||
// Returns the list of usernames.
|
||||
func parseUsersOutput(s string) []string {
|
||||
var users []string
|
||||
for _, userCol := range strings.Split(strings.TrimSpace(s), " ") {
|
||||
users = append(users, userCol)
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
// parseIDOutput parses the output of the `id' command.
|
||||
//
|
||||
// Returns the parsed uid.
|
||||
func parseIDOutput(s string) (int64, error) {
|
||||
uid, err := strconv.ParseInt(strings.TrimSpace(string(s)), 10, 0)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to parse uid: %w", err)
|
||||
}
|
||||
return uid, nil
|
||||
}
|
||||
|
||||
@@ -40,6 +40,12 @@ func buildNFPM(opt Options, pkger nfpm.Packager) (string, error) {
|
||||
updateOpt.RootDirectory = orbitRoot
|
||||
updateOpt.Targets = update.LinuxTargets
|
||||
|
||||
if opt.Desktop {
|
||||
updateOpt.Targets["desktop"] = update.DesktopLinuxTarget
|
||||
// Override default channel with the provided value.
|
||||
updateOpt.Targets.SetTargetChannel("desktop", opt.DesktopChannel)
|
||||
}
|
||||
|
||||
// Override default channels with the provided values.
|
||||
updateOpt.Targets.SetTargetChannel("orbit", opt.OrbitChannel)
|
||||
updateOpt.Targets.SetTargetChannel("osqueryd", opt.OsquerydChannel)
|
||||
@@ -235,6 +241,10 @@ ORBIT_UPDATE_URL={{ .UpdateURL }}
|
||||
ORBIT_ORBIT_CHANNEL={{ .OrbitChannel }}
|
||||
ORBIT_OSQUERYD_CHANNEL={{ .OsquerydChannel }}
|
||||
ORBIT_UPDATE_INTERVAL={{ .OrbitUpdateInterval }}
|
||||
{{ if .Desktop }}
|
||||
ORBIT_FLEET_DESKTOP=true
|
||||
ORBIT_DESKTOP_CHANNEL={{ .DesktopChannel }}
|
||||
{{ end }}
|
||||
{{ if .Insecure }}ORBIT_INSECURE=true{{ end }}
|
||||
{{ if .DisableUpdates }}ORBIT_DISABLE_UPDATES=true{{ end }}
|
||||
{{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }}
|
||||
@@ -295,12 +305,13 @@ func writePostInstall(opt Options, path string) error {
|
||||
}
|
||||
|
||||
func writePreRemove(opt Options, path string) error {
|
||||
// We add `|| true` in case the service is not running
|
||||
// or has been manually disabled already. Otherwise,
|
||||
// uninstallation fails.
|
||||
if err := ioutil.WriteFile(path, []byte(`#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
systemctl stop orbit.service
|
||||
systemctl disable orbit.service
|
||||
systemctl stop orbit.service || true
|
||||
systemctl disable orbit.service || true
|
||||
`), constant.DefaultFileMode); err != nil {
|
||||
return fmt.Errorf("write file: %w", err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
package update
|
||||
|
||||
import "github.com/fleetdm/fleet/v4/orbit/pkg/constant"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/orbit/pkg/constant"
|
||||
)
|
||||
|
||||
// DefaultOptions are the default options to use when creating an update
|
||||
// client.
|
||||
@@ -59,4 +66,19 @@ var (
|
||||
Channel: "stable",
|
||||
TargetFile: constant.DesktopAppExecName + ".exe",
|
||||
}
|
||||
|
||||
DesktopLinuxTarget = TargetInfo{
|
||||
Platform: "linux",
|
||||
Channel: "stable",
|
||||
TargetFile: "desktop.tar.gz",
|
||||
ExtractedExecSubPath: []string{"fleet-desktop", constant.DesktopAppExecName},
|
||||
CustomCheckExec: func(execPath string) error {
|
||||
cmd := exec.Command(execPath, "--help")
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("LD_LIBRARY_PATH=%s:%s", filepath.Dir(execPath), os.ExpandEnv("$LD_LIBRARY_PATH")))
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("exec new version: %s: %w", string(out), err)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -85,6 +85,8 @@ type TargetInfo struct {
|
||||
// ExtractedExecSubPath is the path to the executable in case the
|
||||
// target is a compressed file.
|
||||
ExtractedExecSubPath []string
|
||||
// CustomCheckExec allows for a custom method for checking a downloaded executable.
|
||||
CustomCheckExec func(execPath string) error
|
||||
}
|
||||
|
||||
// New creates a new updater given the provided options. All the necessary
|
||||
@@ -286,7 +288,7 @@ func (u *Updater) Get(target string) (*LocalTarget, error) {
|
||||
}
|
||||
if err := checkFileHash(meta, localTarget.Path); err != nil {
|
||||
log.Debug().Str("info", err.Error()).Msg("change detected")
|
||||
if err := u.download(target, repoPath, localTarget.Path); err != nil {
|
||||
if err := u.download(target, repoPath, localTarget.Path, localTarget.Info.CustomCheckExec); err != nil {
|
||||
return nil, fmt.Errorf("download %q: %w", repoPath, err)
|
||||
}
|
||||
if strings.HasSuffix(localTarget.Path, ".tar.gz") {
|
||||
@@ -299,7 +301,7 @@ func (u *Updater) Get(target string) (*LocalTarget, error) {
|
||||
}
|
||||
case errors.Is(err, os.ErrNotExist):
|
||||
log.Debug().Err(err).Msg("stat file")
|
||||
if err := u.download(target, repoPath, localTarget.Path); err != nil {
|
||||
if err := u.download(target, repoPath, localTarget.Path, localTarget.Info.CustomCheckExec); err != nil {
|
||||
return nil, fmt.Errorf("download %q: %w", repoPath, err)
|
||||
}
|
||||
default:
|
||||
@@ -375,7 +377,7 @@ func (u *Updater) CopyDevBuild(target, devBuildPath string) {
|
||||
|
||||
// download downloads the target to the provided path. The file is deleted and
|
||||
// an error is returned if the hash does not match.
|
||||
func (u *Updater) download(target, repoPath, localPath string) error {
|
||||
func (u *Updater) download(target, repoPath, localPath string, customCheckExec func(execPath string) error) error {
|
||||
staging := filepath.Join(u.opt.RootDirectory, stagingDir)
|
||||
|
||||
if err := secure.MkdirAll(staging, constant.DefaultDirMode); err != nil {
|
||||
@@ -422,7 +424,7 @@ func (u *Updater) download(target, repoPath, localPath string) error {
|
||||
return fmt.Errorf("close tmp file: %w", err)
|
||||
}
|
||||
|
||||
if err := u.checkExec(target, tmp.Name()); err != nil {
|
||||
if err := u.checkExec(target, tmp.Name(), customCheckExec); err != nil {
|
||||
return fmt.Errorf("exec check failed %q: %w", tmp.Name(), err)
|
||||
}
|
||||
|
||||
@@ -452,7 +454,7 @@ func goosFromPlatform(platform string) (string, error) {
|
||||
}
|
||||
|
||||
// checkExec checks/verifies a downloaded executable target by executing it.
|
||||
func (u *Updater) checkExec(target, tmpPath string) error {
|
||||
func (u *Updater) checkExec(target, tmpPath string, customCheckExec func(execPath string) error) error {
|
||||
localTarget, err := u.localTarget(target)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -477,11 +479,18 @@ func (u *Updater) checkExec(target, tmpPath string) error {
|
||||
tmpPath = filepath.Join(append([]string{filepath.Dir(tmpPath)}, localTarget.Info.ExtractedExecSubPath...)...)
|
||||
}
|
||||
|
||||
// Note that this would fail for any binary that returns nonzero for --help.
|
||||
out, err := exec.Command(tmpPath, "--help").CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("exec new version: %s: %w", string(out), err)
|
||||
if customCheckExec != nil {
|
||||
if err := customCheckExec(tmpPath); err != nil {
|
||||
return fmt.Errorf("custom exec new version failed: %w", err)
|
||||
}
|
||||
} else {
|
||||
// Note that this would fail for any binary that returns nonzero for --help.
|
||||
cmd := exec.Command(tmpPath, "--help")
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("exec new version: %s: %w", string(out), err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,11 @@ func createMacOSApp(version, authority string, notarize bool) error {
|
||||
}
|
||||
|
||||
/* #nosec G204 -- arguments are actually well defined */
|
||||
buildExec := exec.Command("go", "build", "-o", filepath.Join(macOSDir, constant.DesktopAppExecName), "./"+filepath.Join("orbit", "cmd", "desktop"))
|
||||
buildExec := exec.Command("go", "build",
|
||||
"-o", filepath.Join(macOSDir, constant.DesktopAppExecName),
|
||||
"-ldflags", os.ExpandEnv("-X=main.version=$FLEET_DESKTOP_VERSION"),
|
||||
"./"+filepath.Join("orbit", "cmd", "desktop"),
|
||||
)
|
||||
buildExec.Env = append(os.Environ(), "CGO_ENABLED=1")
|
||||
buildExec.Stderr = os.Stderr
|
||||
buildExec.Stdout = os.Stdout
|
||||
|
||||
@@ -89,6 +89,19 @@ function create_repository() {
|
||||
rm fleet-desktop.exe
|
||||
fi
|
||||
|
||||
# Add Fleet Desktop application on (if enabled).
|
||||
if [[ $system == "linux" && -n "$FLEET_DESKTOP" ]]; then
|
||||
FLEET_DESKTOP_VERSION=42.0.0 \
|
||||
make desktop-linux
|
||||
./build/fleetctl updates add \
|
||||
--path $TUF_PATH \
|
||||
--target desktop.tar.gz \
|
||||
--platform linux \
|
||||
--name desktop \
|
||||
--version 42.0.0 -t 42.0 -t 42 -t stable
|
||||
rm desktop.tar.gz
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
# Generate and add osqueryd .app bundle for macos-app.
|
||||
@@ -146,6 +159,7 @@ if [ -n "$GENERATE_PKGS" ]; then
|
||||
echo "Generating deb..."
|
||||
./build/fleetctl package \
|
||||
--type=deb \
|
||||
${FLEET_DESKTOP:+--fleet-desktop} \
|
||||
--fleet-url=https://$DEB_HOSTNAME:8080 \
|
||||
--enroll-secret=$ENROLL_SECRET \
|
||||
--insecure \
|
||||
@@ -158,6 +172,7 @@ if [ -n "$GENERATE_PKGS" ]; then
|
||||
echo "Generating rpm..."
|
||||
./build/fleetctl package \
|
||||
--type=rpm \
|
||||
${FLEET_DESKTOP:+--fleet-desktop} \
|
||||
--fleet-url=https://$RPM_HOSTNAME:8080 \
|
||||
--enroll-secret=$ENROLL_SECRET \
|
||||
--insecure \
|
||||
|
||||
Reference in New Issue
Block a user