From 7a5439e4da7d1de9634fc6ce7b30c8067d51c002 Mon Sep 17 00:00:00 2001 From: Amogh Rathore Date: Tue, 17 Sep 2024 12:03:51 -0700 Subject: [PATCH] Check if nsenter is available and bind mount it on Agent container (#4341) --- ecs-init/docker/docker_config.go | 17 ++++++++++++ ecs-init/docker/docker_config_test.go | 38 +++++++++++++++++++++++++++ ecs-init/docker/docker_test.go | 2 +- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 ecs-init/docker/docker_config_test.go diff --git a/ecs-init/docker/docker_config.go b/ecs-init/docker/docker_config.go index bfc5cf8c792..d4f4b95549d 100644 --- a/ecs-init/docker/docker_config.go +++ b/ecs-init/docker/docker_config.go @@ -15,8 +15,10 @@ package docker import ( "fmt" + "os" "github.com/aws/amazon-ecs-agent/ecs-init/config" + "github.com/cihub/seelog" ctrdapparmor "github.com/containerd/containerd/pkg/apparmor" godocker "github.com/fsouza/go-dockerclient" ) @@ -45,6 +47,7 @@ func createHostConfig(binds []string) *godocker.HostConfig { iptablesLegacyDir+":"+iptablesLegacyDir+readOnly, "/usr/bin/lsblk:/usr/bin/lsblk", ) + binds = append(binds, getNsenterBinds(os.Stat)...) logConfig := config.AgentDockerLogDriverConfiguration() @@ -80,3 +83,17 @@ func createHostConfig(binds []string) *godocker.HostConfig { return hostConfig } + +// Returns nsenter bind as a slice if nsenter is available on the host. +// Returns an empty slice otherwise. +func getNsenterBinds(statFn func(string) (os.FileInfo, error)) []string { + binds := []string{} + const nsenterPath = "/usr/bin/nsenter" + if _, err := statFn(nsenterPath); err == nil { + binds = append(binds, nsenterPath+":"+nsenterPath) + } else { + seelog.Warnf("nsenter not found at %s, skip binding it to Agent container: %v", + nsenterPath, err) + } + return binds +} diff --git a/ecs-init/docker/docker_config_test.go b/ecs-init/docker/docker_config_test.go new file mode 100644 index 00000000000..a71ef2b291b --- /dev/null +++ b/ecs-init/docker/docker_config_test.go @@ -0,0 +1,38 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. + +package docker + +import ( + "errors" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetNsenterBinds(t *testing.T) { + t.Run("nsenter not found", func(t *testing.T) { + binds := getNsenterBinds( + func(s string) (os.FileInfo, error) { return nil, errors.New("not found") }) + assert.Empty(t, binds) + }) + + t.Run("nsenter is found", func(t *testing.T) { + binds := getNsenterBinds( + func(s string) (os.FileInfo, error) { return nil, nil }) + require.Len(t, binds, 1) + assert.Equal(t, "/usr/bin/nsenter:/usr/bin/nsenter", binds[0]) + }) +} diff --git a/ecs-init/docker/docker_test.go b/ecs-init/docker/docker_test.go index c08f3872c03..0f7348ab8fc 100644 --- a/ecs-init/docker/docker_test.go +++ b/ecs-init/docker/docker_test.go @@ -32,7 +32,7 @@ import ( // Note: Change this value every time when a new bind mount is added to // agent for the tests to pass const ( - defaultExpectedAgentBinds = 20 + defaultExpectedAgentBinds = 21 ) func TestIsAgentImageLoadedListFailure(t *testing.T) {