Skip to content

Commit 03b5d31

Browse files
Extend agent container initialisation logic (elastic#4925)
* feat: implement container initialisation that chowns related paths and raises capabilities * doc: add changelog fragment * fix: update NOTICE.txt * fix: typo in container_init_test.go * feat: add more unit-tests to increase coverage * feat: utilise unix.Exec to re-exec elastic-agent when file capabilities are updated * fix: handle err from utils.HasRoot * fix: refactor skip-file-capabilities flag * fix: add cap_setpcap at elastic-agent binary * feat: make npm install work with elastic-agent user * fix: remove --skip-file-capabilities flag * fix: allow CAP_CHOWN in Ambient set * fix: remove redundant comment from Dockerfile.elastic-agent.tmpl * fix: remove IDE auto-corrections from NOTICE.txt * chore: go mod tidy after merge * feat: refactor to eliminate disrupting effects * fix: correct import order * fix: move logWarning inside container_init_linux.go * fix: update NOTICE.txt * fix: call initContainer before tryContainerLoadPaths for elastic-agent container * fix: revert npm installation changes in agent container image * fix: chown also symlinks * fix: introduce support for inside kubernetes tests * fix: permission for configuration configmap mount to support rootless agent * fix: code format * feat: revisit the runAsUser and runAsGroup in k8s test * fix: go mod tidy * fix: wrap errors in fmt.Errorf * fix: update NOTICE.txt * feat: add comments in container_init_linux.go * fix: adjust artifact_paths to extract all artifacts * fix: permission for configuration configmap mount to support rootless agent at base k8s files * fix: log stderr for k8s inner tests * fix: disable CGO for k8s inner tests * fix: merge conflicts * fix: permission for configuration configmap mount to support rootless agent at base k8s files * fix: improve logging the output of status command when elastic-agent doesn't report healthy * fix: revert back to pre-1.22 golang for loop to make linter happy * fix: don't set runAsGroup inside k8s tests for deployment with root and elastic-agent uid * fix: add DAC_READ_SEARCH capability in k8s tests for deployment with random uid and gid * fix: add comment to elaborate why call initContainer before tryContainerLoadPaths
1 parent 96b9388 commit 03b5d31

File tree

21 files changed

+2501
-324
lines changed

21 files changed

+2501
-324
lines changed

.buildkite/pipeline.yml

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ steps:
206206
command: ".buildkite/scripts/steps/k8s-extended-tests.sh"
207207
artifact_paths:
208208
- "build/k8s-logs*/*"
209+
- "build/k8s-logs*/**/*"
209210
- "build/TEST-**"
210211
- "build/diagnostics/*"
211212
agents:

NOTICE.txt

+1,054-238
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: feature
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: extend agent container initialisation to chown paths and raise capabilities for non-root
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
#description:
20+
21+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
22+
component: elastic-agent
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
pr: https://github.com/elastic/elastic-agent/pull/4925
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
#issue: https://github.com/owner/repo/1234

deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ spec:
6666
valueFrom:
6767
fieldRef:
6868
fieldPath: metadata.name
69-
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
69+
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
7070
# For more info: https://www.elastic.co/guide/en/beats/metricbeat/current/add-host-metadata.html
7171
- name: ELASTIC_NETINFO
7272
value: "false"
@@ -127,7 +127,7 @@ spec:
127127
volumes:
128128
- name: datastreams
129129
configMap:
130-
defaultMode: 0640
130+
defaultMode: 0644
131131
name: agent-node-datastreams
132132
- name: proc
133133
hostPath:

deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/base/elastic-agent-standalone-daemonset.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ spec:
6666
valueFrom:
6767
fieldRef:
6868
fieldPath: metadata.name
69-
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
69+
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
7070
# For more info: https://www.elastic.co/guide/en/beats/metricbeat/current/add-host-metadata.html
7171
- name: ELASTIC_NETINFO
7272
value: "false"
@@ -127,7 +127,7 @@ spec:
127127
volumes:
128128
- name: datastreams
129129
configMap:
130-
defaultMode: 0640
130+
defaultMode: 0644
131131
name: agent-node-datastreams
132132
- name: proc
133133
hostPath:

deploy/kubernetes/elastic-agent-kustomize/ksm-autosharding/elastic-agent-standalone/extra/elastic-agent-standalone-statefulset.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ spec:
6666
valueFrom:
6767
fieldRef:
6868
fieldPath: metadata.name
69-
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
69+
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
7070
# For more info: https://www.elastic.co/guide/en/beats/metricbeat/current/add-host-metadata.html
7171
- name: ELASTIC_NETINFO
7272
value: "false"
@@ -127,7 +127,7 @@ spec:
127127
volumes:
128128
- name: datastreams
129129
configMap:
130-
defaultMode: 0640
130+
defaultMode: 0644
131131
name: agent-ksm-datastreams
132132
- name: proc
133133
hostPath:

deploy/kubernetes/elastic-agent-standalone-kubernetes.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ spec:
735735
valueFrom:
736736
fieldRef:
737737
fieldPath: metadata.name
738-
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
738+
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
739739
# For more info: https://www.elastic.co/guide/en/beats/metricbeat/current/add-host-metadata.html
740740
- name: ELASTIC_NETINFO
741741
value: "false"
@@ -796,7 +796,7 @@ spec:
796796
volumes:
797797
- name: datastreams
798798
configMap:
799-
defaultMode: 0640
799+
defaultMode: 0644
800800
name: agent-node-datastreams
801801
- name: proc
802802
hostPath:

deploy/kubernetes/elastic-agent-standalone/elastic-agent-standalone-daemonset.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ spec:
6666
valueFrom:
6767
fieldRef:
6868
fieldPath: metadata.name
69-
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
69+
# The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac.
7070
# For more info: https://www.elastic.co/guide/en/beats/metricbeat/current/add-host-metadata.html
7171
- name: ELASTIC_NETINFO
7272
value: "false"
@@ -127,7 +127,7 @@ spec:
127127
volumes:
128128
- name: datastreams
129129
configMap:
130-
defaultMode: 0640
130+
defaultMode: 0644
131131
name: agent-node-datastreams
132132
- name: proc
133133
hostPath:

dev-tools/mage/gotest.go

+27
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,33 @@ func InstallGoTestTools() error {
176176
)
177177
}
178178

179+
func GoTestBuild(ctx context.Context, params GoTestArgs) error {
180+
if params.OutputFile == "" {
181+
return fmt.Errorf("missing output file")
182+
}
183+
184+
fmt.Println(">> go test:", params.LogName, "Building Test Binary")
185+
186+
args := []string{"test", "-c", "-o", params.OutputFile}
187+
188+
if len(params.Tags) > 0 {
189+
params := strings.Join(params.Tags, " ")
190+
if params != "" {
191+
args = append(args, "-tags", params)
192+
}
193+
}
194+
195+
args = append(args, params.Packages...)
196+
197+
goTestBuild := makeCommand(ctx, params.Env, "go", args...)
198+
199+
err := goTestBuild.Run()
200+
if err != nil {
201+
return err
202+
}
203+
return nil
204+
}
205+
179206
// GoTest invokes "go test" and reports the results to stdout. It returns an
180207
// error if there was any failure executing the tests or if there were any
181208
// test failures.

dev-tools/packaging/templates/docker/Dockerfile.elastic-agent.tmpl

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ RUN true && \
5656
true
5757

5858
# Keep this after any chown command, chown resets any applied capabilities
59+
RUN setcap =p {{ $beatHome }}/data/elastic-agent-{{ commit_short }}/elastic-agent
5960
RUN setcap cap_net_raw,cap_setuid+p {{ $beatHome }}/data/elastic-agent-{{ commit_short }}/components/agentbeat && \
6061
{{- if .linux_capabilities }}
6162
# Since the beat is stored at the other end of a symlink we must follow the symlink first

go.mod

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
1111
github.com/cavaliercoder/go-rpm v0.0.0-20190131055624-7a9c54e3d83e
1212
github.com/cenkalti/backoff/v4 v4.3.0
13+
github.com/docker/docker v26.1.4+incompatible
1314
github.com/docker/go-units v0.5.0
1415
github.com/dolmen-go/contextio v0.0.0-20200217195037-68fc5150bcd5
1516
github.com/elastic/elastic-agent-autodiscover v0.8.0
@@ -63,6 +64,7 @@ require (
6364
go.elastic.co/go-licence-detector v0.6.1
6465
go.uber.org/zap v1.27.0
6566
golang.org/x/crypto v0.25.0
67+
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
6668
golang.org/x/sync v0.7.0
6769
golang.org/x/sys v0.22.0
6870
golang.org/x/term v0.22.0
@@ -80,6 +82,7 @@ require (
8082
k8s.io/apimachinery v0.30.1
8183
k8s.io/client-go v0.30.1
8284
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
85+
kernel.org/pub/linux/libs/security/libcap/cap v1.2.70
8386
sigs.k8s.io/e2e-framework v0.4.0
8487
sigs.k8s.io/kustomize/api v0.12.1
8588
sigs.k8s.io/kustomize/kyaml v0.13.9
@@ -143,7 +146,6 @@ require (
143146
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
144147
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
145148
github.com/dnephin/pflag v1.0.7 // indirect
146-
github.com/docker/docker v26.1.4+incompatible // indirect
147149
github.com/docker/go-connections v0.5.0 // indirect
148150
github.com/elastic/go-docappender/v2 v2.2.0 // indirect
149151
github.com/elastic/go-elasticsearch/v7 v7.17.10 // indirect
@@ -312,7 +314,6 @@ require (
312314
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
313315
go.starlark.net v0.0.0-20221205180719-3fd0dac74452 // indirect
314316
go.uber.org/multierr v1.11.0 // indirect
315-
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
316317
golang.org/x/mod v0.18.0 // indirect
317318
golang.org/x/net v0.27.0 // indirect
318319
golang.org/x/oauth2 v0.21.0 // indirect
@@ -324,6 +325,7 @@ require (
324325
howett.net/plist v1.0.1 // indirect
325326
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
326327
k8s.io/kubelet v0.29.3 // indirect
328+
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 // indirect
327329
sigs.k8s.io/controller-runtime v0.18.2 // indirect
328330
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
329331
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -2471,6 +2471,10 @@ k8s.io/kubelet v0.29.3/go.mod h1:jDiGuTkFOUynyBKzOoC1xRSWlgAZ9UPcTYeFyjr6vas=
24712471
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
24722472
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
24732473
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
2474+
kernel.org/pub/linux/libs/security/libcap/cap v1.2.70 h1:QnLPkuDWWbD5C+3DUA2IUXai5TK6w2zff+MAGccqdsw=
2475+
kernel.org/pub/linux/libs/security/libcap/cap v1.2.70/go.mod h1:/iBwcj9nbLejQitYvUm9caurITQ6WyNHibJk6Q9fiS4=
2476+
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70 h1:HsB2G/rEQiYyo1bGoQqHZ/Bvd6x1rERQTNdPr1FyWjI=
2477+
kernel.org/pub/linux/libs/security/libcap/psx v1.2.70/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
24742478
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
24752479
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
24762480
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=

internal/pkg/agent/cmd/common.go

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ func NewCommandWithArgs(args []string, streams *cli.IOStreams) *cobra.Command {
3737
cmd := &cobra.Command{
3838
Use: "elastic-agent [subcommand]",
3939
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
40+
if cmd.Name() == "container" {
41+
// need to initialize container and try to chown agent-related paths
42+
// before tryContainerLoadPaths as this will try to read/write from
43+
// the agent state dir which might not have proper permissions when
44+
// running inside a container
45+
initContainer(streams)
46+
}
47+
4048
return tryContainerLoadPaths()
4149
},
4250
}

internal/pkg/agent/cmd/container.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ import (
4343
const (
4444
requestRetrySleepEnv = "KIBANA_REQUEST_RETRY_SLEEP"
4545
maxRequestRetriesEnv = "KIBANA_REQUEST_RETRY_COUNT"
46-
defaultRequestRetrySleep = "1s" // sleep 1 sec between retries for HTTP requests
47-
defaultMaxRequestRetries = "30" // maximum number of retries for HTTP requests
48-
defaultStateDirectory = "/usr/share/elastic-agent/state" // directory that will hold the state data
46+
defaultRequestRetrySleep = "1s" // sleep 1 sec between retries for HTTP requests
47+
defaultMaxRequestRetries = "30" // maximum number of retries for HTTP requests
48+
agentBaseDirectory = "/usr/share/elastic-agent" // directory that holds all elastic-agent related files
49+
defaultStateDirectory = agentBaseDirectory + "/state" // directory that will hold the state data
4950

5051
logsPathPerms = 0775
5152
)
@@ -153,6 +154,7 @@ occurs on every start of the container set FLEET_FORCE to 1.
153154
}
154155
},
155156
}
157+
156158
return &cmd
157159
}
158160

0 commit comments

Comments
 (0)