Skip to content

Commit eaafbd0

Browse files
feat: implement a proxy binary to be placed in the root of windows archive and invoke the nested elastic-agent binary
1 parent 5cff614 commit eaafbd0

File tree

5 files changed

+151
-3
lines changed

5 files changed

+151
-3
lines changed

dev-tools/packaging/packages.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ shared:
333333
'data/{{.BeatName}}-{{ commit_short }}/components/agentbeat.spec.yml':
334334
source: '{{.AgentDropPath}}/{{.GOOS}}-{{.AgentArchName}}.tar.gz/agentbeat.spec.yml'
335335
expand_spec: true
336-
336+
337337
- &agent_docker_edot_wolfi_spec
338338
<<: *agent_docker_edot_spec
339339
docker_variant: 'elastic-otel-collector-wolfi'
@@ -370,7 +370,7 @@ shared:
370370
'data/{{.BeatName}}-{{ commit_short }}/components/pf-host-agent.spec.yml':
371371
source: '{{.AgentDropPath}}/{{.GOOS}}-{{.AgentArchName}}.tar.gz/pf-host-agent.spec.yml'
372372
expand_spec: true
373-
373+
374374
- &agent_docker_slim_wolfi_spec
375375
<<: *agent_docker_slim_spec
376376
docker_variant: 'slim-wolfi'
@@ -922,7 +922,7 @@ specs:
922922
<<: *elastic_license_for_binaries
923923
files:
924924
'{{.BeatName}}{{.BinaryExt}}':
925-
source: ./build/golang-crossbuild/{{.BeatName}}-{{.GOOS}}-{{.Platform.Arch}}{{.BinaryExt}}
925+
source: ./build/windows-archive-root-binary/elastic-agent-archive-root.exe
926926
'package.version':
927927
content: >
928928
{{ agent_package_version }}

hack/windows/archive-proxy/go.mod

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/hack/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 => ../../../

hack/windows/archive-proxy/go.sum

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=

hack/windows/archive-proxy/main.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
"fmt"
9+
"log"
10+
"os"
11+
"os/exec"
12+
"path/filepath"
13+
14+
"github.com/elastic/elastic-agent/pkg/core/process"
15+
)
16+
17+
var CommitSHA string
18+
19+
func main() {
20+
if CommitSHA == "" {
21+
// this should never happen
22+
log.Fatal("No commit SHA provided")
23+
}
24+
25+
exePath, err := os.Executable()
26+
if err != nil {
27+
log.Fatalf("Error getting executable path: %v\n", err)
28+
return
29+
}
30+
31+
exeAbsPath, err := filepath.Abs(exePath)
32+
if err != nil {
33+
log.Fatalf("Error getting executable absolute path: %v\n", err)
34+
return
35+
}
36+
37+
// Fabricate the elastic-agent.exe path that reside inside the data/elastic-agent-{commit-short-sha} directory
38+
exeTopPath := filepath.Dir(exeAbsPath)
39+
nestedAgentBinaryPath := filepath.Join(exeTopPath, "data", fmt.Sprintf("elastic-agent-%s", CommitSHA), "elastic-agent.exe")
40+
if _, err := os.Stat(nestedAgentBinaryPath); err != nil {
41+
log.Fatalf("Unable to stat nested agent binary %q: %v\n", nestedAgentBinaryPath, err)
42+
}
43+
44+
// Create the arguments
45+
var args []string
46+
if len(os.Args) > 1 {
47+
args = os.Args[1:]
48+
}
49+
50+
g, err := process.CreateJobObject()
51+
if err != nil {
52+
log.Fatalf("Unable to create job object: %v\n", err)
53+
}
54+
defer func() {
55+
_ = g.Close()
56+
}()
57+
58+
// Create the command
59+
command := exec.Command(nestedAgentBinaryPath, args...)
60+
61+
// Forward stdout, stderr, stdin
62+
command.Stdout = os.Stdout
63+
command.Stderr = os.Stderr
64+
command.Stdin = os.Stdin
65+
66+
// Pass the environment
67+
command.Env = os.Environ()
68+
69+
// Run the command
70+
err = command.Start()
71+
if err != nil {
72+
log.Fatalf("Error running command: %v\n", err)
73+
}
74+
75+
// Add the process to the job object
76+
if err := g.Assign(command.Process); err != nil {
77+
log.Fatalf("Error adding job object: %v\n", err)
78+
}
79+
80+
_ = command.Wait()
81+
}

magefile.go

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

297+
// WindowsArchiveRootBinary compiles a binary to be placed at the root of the windows elastic-agent archive. This binary
298+
// is a thin proxy to the actual elastic-agent binary that resides in the data/elastic-agent-{commit-short-sha}
299+
// directory of the archive.
300+
func (Build) WindowsArchiveRootBinary() error {
301+
fmt.Println("--- Compiling root binary for windows archive")
302+
hashShort, err := devtools.CommitHashShort()
303+
if err != nil {
304+
return fmt.Errorf("error getting commit hash: %w", err)
305+
}
306+
307+
outputName := "elastic-agent-archive-root"
308+
if runtime.GOOS != "windows" {
309+
// add the .exe extension on non-windows platforms
310+
outputName += ".exe"
311+
}
312+
313+
args := devtools.BuildArgs{
314+
Name: outputName,
315+
OutputDir: filepath.Join(buildDir, "windows-archive-root-binary"),
316+
InputFiles: []string{"hack/windows/archive-proxy/main.go"},
317+
CGO: false,
318+
WinMetadata: true,
319+
ExtraFlags: []string{
320+
"-buildmode", "pie", // windows versions inside the support matrix do support position independent code
321+
"-trimpath", // Remove all file system paths from the compiled executable, to improve build reproducibility
322+
},
323+
Vars: map[string]string{
324+
"main.CommitSHA": hashShort,
325+
},
326+
Env: map[string]string{
327+
"GOOS": "windows",
328+
"GOARCH": "amd64",
329+
},
330+
LDFlags: []string{
331+
"-s", // Strip all debug symbols from binary (does not affect Go stack traces).
332+
},
333+
}
334+
335+
if devtools.FIPSBuild {
336+
// there is no actual FIPS relevance for this particular binary
337+
// but better safe than sorry
338+
args.ExtraFlags = append(args.ExtraFlags, "-tags=requirefips")
339+
args.CGO = true
340+
}
341+
342+
return devtools.Build(args)
343+
}
344+
297345
// GolangCrossBuildOSS build the Beat binary inside of the golang-builder.
298346
// Do not use directly, use crossBuild instead.
299347
func GolangCrossBuildOSS() error {
@@ -1022,6 +1070,15 @@ func packageAgent(ctx context.Context, platforms []string, dependenciesVersion s
10221070
log.Println("--- Running post packaging ")
10231071
mg.Deps(Update)
10241072
mg.Deps(agentBinaryTarget, CrossBuildGoDaemon)
1073+
1074+
// compile the elastic-agent.exe proxy binary for the windows archive
1075+
for _, platform := range platforms {
1076+
if platform == "windows/amd64" {
1077+
mg.Deps(Build.WindowsArchiveRootBinary)
1078+
break
1079+
}
1080+
}
1081+
10251082
mg.SerialDeps(devtools.Package, TestPackages)
10261083
return nil
10271084
}

0 commit comments

Comments
 (0)