Skip to content

Commit d151d35

Browse files
[8.18](backport #7601) [packaging] proxy binary to be for the root dir of windows archive (#7638)
* [packaging] proxy binary to be for the root dir of windows archive (#7601) * feat: implement a proxy binary to be placed in the root of windows archive and invoke the nested elastic-agent binary * fix: remove redundant returns in the code * fix: reword error message when we cannot stat inner elastic-agent binary * fix: use slices.Contains to check if we are building for windows/amd64 * fix: add comment to capture that CommitSHA is set at build time * fix: rename hack folder to wrapper * fix: reside typo * fix: reword error message when we cannot stat inner elastic-agent binary * ci: automate go version updates for wrapper/windows/archive-proxy/go.mod * fix: switch logging to fmt and also log to windows event logger * Revert "ci: automate go version updates for wrapper/windows/archive-proxy/go.mod" This reverts commit c9a698b. * fix: initialise windows event log only if we are admin * fix: remove os.Stat call and rely on command.Start() to raise an error if binary is missing * fix: remove custom logger (cherry picked from commit 6b4b0dc) # Conflicts: # dev-tools/packaging/packages.yml * fix: resolve conflicts --------- Co-authored-by: Panos Koutsovasilis <[email protected]>
1 parent 01650a7 commit d151d35

File tree

5 files changed

+158
-1
lines changed

5 files changed

+158
-1
lines changed

dev-tools/packaging/packages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ specs:
876876
<<: *elastic_license_for_binaries
877877
files:
878878
'{{.BeatName}}{{.BinaryExt}}':
879-
source: ./build/golang-crossbuild/{{.BeatName}}-{{.GOOS}}-{{.Platform.Arch}}{{.BinaryExt}}
879+
source: ./build/windows-archive-root-binary/elastic-agent-archive-root.exe
880880
'package.version':
881881
content: >
882882
{{ agent_package_version }}

magefile.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,54 @@ func (Build) GenerateConfig() error {
292292
return sh.Copy(filepath.Join(buildDir, configFile), filepath.Join(metaDir, configFile))
293293
}
294294

295+
// WindowsArchiveRootBinary compiles a binary to be placed at the root of the windows elastic-agent archive. This binary
296+
// is a thin proxy to the actual elastic-agent binary that resides in the data/elastic-agent-{commit-short-sha}
297+
// directory of the archive.
298+
func (Build) WindowsArchiveRootBinary() error {
299+
fmt.Println("--- Compiling root binary for windows archive")
300+
hashShort, err := devtools.CommitHashShort()
301+
if err != nil {
302+
return fmt.Errorf("error getting commit hash: %w", err)
303+
}
304+
305+
outputName := "elastic-agent-archive-root"
306+
if runtime.GOOS != "windows" {
307+
// add the .exe extension on non-windows platforms
308+
outputName += ".exe"
309+
}
310+
311+
args := devtools.BuildArgs{
312+
Name: outputName,
313+
OutputDir: filepath.Join(buildDir, "windows-archive-root-binary"),
314+
InputFiles: []string{"wrapper/windows/archive-proxy/main.go"},
315+
CGO: false,
316+
WinMetadata: true,
317+
ExtraFlags: []string{
318+
"-buildmode", "pie", // windows versions inside the support matrix do support position independent code
319+
"-trimpath", // Remove all file system paths from the compiled executable, to improve build reproducibility
320+
},
321+
Vars: map[string]string{
322+
"main.CommitSHA": hashShort,
323+
},
324+
Env: map[string]string{
325+
"GOOS": "windows",
326+
"GOARCH": "amd64",
327+
},
328+
LDFlags: []string{
329+
"-s", // Strip all debug symbols from binary (does not affect Go stack traces).
330+
},
331+
}
332+
333+
if devtools.FIPSBuild {
334+
// there is no actual FIPS relevance for this particular binary
335+
// but better safe than sorry
336+
args.ExtraFlags = append(args.ExtraFlags, "-tags=requirefips")
337+
args.CGO = true
338+
}
339+
340+
return devtools.Build(args)
341+
}
342+
295343
// GolangCrossBuildOSS build the Beat binary inside of the golang-builder.
296344
// Do not use directly, use crossBuild instead.
297345
func GolangCrossBuildOSS() error {
@@ -1007,6 +1055,12 @@ func packageAgent(ctx context.Context, platforms []string, dependenciesVersion s
10071055
log.Println("--- Running post packaging ")
10081056
mg.Deps(Update)
10091057
mg.Deps(agentBinaryTarget, CrossBuildGoDaemon)
1058+
1059+
// compile the elastic-agent.exe proxy binary for the windows archive
1060+
if slices.Contains(platforms, "windows/amd64") {
1061+
mg.Deps(Build.WindowsArchiveRootBinary)
1062+
}
1063+
10101064
mg.SerialDeps(devtools.Package, TestPackages)
10111065
return nil
10121066
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module github.com/elastic/elastic-agent/wrapper/windows/archive-proxy
2+
3+
go 1.24.1
4+
5+
require github.com/elastic/elastic-agent v0.0.0
6+
7+
require golang.org/x/sys v0.31.0 // indirect
8+
9+
replace github.com/elastic/elastic-agent => ../../../
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
2+
// or more contributor license agreements. Licensed under the Elastic License 2.0;
3+
// you may not use this file except in compliance with the Elastic License 2.0.
4+
5+
package main
6+
7+
import (
8+
"errors"
9+
"fmt"
10+
"log"
11+
"os"
12+
"os/exec"
13+
"path/filepath"
14+
15+
"github.com/elastic/elastic-agent/pkg/core/process"
16+
)
17+
18+
// CommitSHA is set by the linker at build time
19+
var CommitSHA string
20+
21+
func main() {
22+
log.SetFlags(0)
23+
if CommitSHA == "" {
24+
// this should never happen
25+
log.Fatal("No commit SHA provided\n")
26+
}
27+
28+
exePath, err := os.Executable()
29+
if err != nil {
30+
log.Fatalf("Error getting executable path: %v\n", err)
31+
}
32+
33+
exeAbsPath, err := filepath.Abs(exePath)
34+
if err != nil {
35+
log.Fatalf("Error getting executable absolute path: %v\n", err)
36+
}
37+
38+
// Fabricate the elastic-agent.exe path that resides inside the data/elastic-agent-{commit-short-sha} directory
39+
exeTopPath := filepath.Dir(exeAbsPath)
40+
nestedAgentBinaryPath := filepath.Join(exeTopPath, "data", fmt.Sprintf("elastic-agent-%s", CommitSHA), "elastic-agent.exe")
41+
42+
// Create the arguments
43+
var args []string
44+
if len(os.Args) > 1 {
45+
args = os.Args[1:]
46+
}
47+
48+
g, err := process.CreateJobObject()
49+
if err != nil {
50+
log.Fatalf("Unable to create job object: %v\n", err)
51+
}
52+
defer func() {
53+
_ = g.Close()
54+
}()
55+
56+
// Create the command
57+
command := exec.Command(nestedAgentBinaryPath, args...)
58+
59+
// Forward stdout, stderr, stdin
60+
command.Stdout = os.Stdout
61+
command.Stderr = os.Stderr
62+
command.Stdin = os.Stdin
63+
64+
// Pass the environment
65+
command.Env = os.Environ()
66+
67+
// Run the command
68+
err = command.Start()
69+
if err != nil {
70+
log.Fatalf("Error running command: %v\n", err)
71+
}
72+
73+
// Add the process to the job object
74+
if err := g.Assign(command.Process); err != nil {
75+
log.Fatalf("Error adding job object: %v\n", err)
76+
}
77+
78+
err = command.Wait()
79+
var exitError *exec.ExitError
80+
switch {
81+
case errors.As(err, &exitError):
82+
exitCode := exitError.ExitCode()
83+
if exitCode == 0 {
84+
// Exit with non-zero exit code since we did get an error
85+
os.Exit(1)
86+
}
87+
// Exit with the same exit code
88+
os.Exit(exitCode)
89+
case err != nil:
90+
// Exit with a non-zero exit code
91+
log.Fatalf("Command failed: %v\n", err)
92+
}
93+
}

0 commit comments

Comments
 (0)