Skip to content

Commit

Permalink
Load pause container image by default on linux.
Browse files Browse the repository at this point in the history
This commits addresses the issue on #2290. Load pause container image by default. Enforce pid/ipc capabilities append to check for existence of pause container image
  • Loading branch information
suneyz committed Dec 4, 2019
1 parent 9e40df4 commit 69ef247
Show file tree
Hide file tree
Showing 14 changed files with 423 additions and 9 deletions.
5 changes: 5 additions & 0 deletions agent/app/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ func (agent *ecsAgent) doStart(containerChangeEventStream *eventstream.EventStre
return exitcodes.ExitTerminal
}

err = agent.loadPauseContainer()
if err != nil {
seelog.Error("Failed to load pause container: %v", err)
}

var vpcSubnetAttributes []*ecs.Attribute
// Check if Task ENI is enabled
if agent.cfg.TaskENIEnabled {
Expand Down
56 changes: 56 additions & 0 deletions agent/app/agent_capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"strings"
"testing"

mock_pause "github.com/aws/amazon-ecs-agent/agent/eni/pause/mocks"

"github.com/aws/amazon-ecs-agent/agent/ecs_client/model/ecs"

"context"
Expand All @@ -46,6 +48,7 @@ func TestCapabilities(t *testing.T) {
cniClient := mock_ecscni.NewMockCNIClient(ctrl)
mockCredentialsProvider := app_mocks.NewMockProvider(ctrl)
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)
mockPauseLoader := mock_pause.NewMockLoader(ctrl)
conf := &config.Config{
AvailableLoggingDrivers: []dockerclient.LoggingDriver{
dockerclient.JSONFileDriver,
Expand All @@ -61,6 +64,8 @@ func TestCapabilities(t *testing.T) {
AWSVPCBlockInstanceMetdata: true,
TaskCleanupWaitDuration: config.DefaultConfig().TaskCleanupWaitDuration,
}

mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()
// Scan() and ListPluginsWithFilters() are tested with
// AnyTimes() because they are not called in windows.
gomock.InOrder(
Expand Down Expand Up @@ -142,6 +147,7 @@ func TestCapabilities(t *testing.T) {
cfg: conf,
dockerClient: client,
cniClient: cniClient,
pauseLoader: mockPauseLoader,
credentialProvider: aws_credentials.NewCredentials(mockCredentialsProvider),
mobyPlugins: mockMobyPlugins,
}
Expand Down Expand Up @@ -169,12 +175,16 @@ func TestCapabilitiesECR(t *testing.T) {
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
pauseLoader: mockPauseLoader,
dockerClient: client,
mobyPlugins: mockMobyPlugins,
}
Expand Down Expand Up @@ -211,13 +221,17 @@ func TestCapabilitiesTaskIAMRoleForSupportedDockerVersion(t *testing.T) {
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}
capabilities, err := agent.capabilities()
Expand Down Expand Up @@ -250,13 +264,17 @@ func TestCapabilitiesTaskIAMRoleForUnSupportedDockerVersion(t *testing.T) {
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand Down Expand Up @@ -290,13 +308,17 @@ func TestCapabilitiesTaskIAMRoleNetworkHostForSupportedDockerVersion(t *testing.
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand Down Expand Up @@ -330,13 +352,17 @@ func TestCapabilitiesTaskIAMRoleNetworkHostForUnSupportedDockerVersion(t *testin
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -359,6 +385,7 @@ func TestAWSVPCBlockInstanceMetadataWhenTaskENIIsDisabled(t *testing.T) {
client := mock_dockerapi.NewMockDockerClient(ctrl)
cniClient := mock_ecscni.NewMockCNIClient(ctrl)
mockCredentialsProvider := app_mocks.NewMockProvider(ctrl)
mockPauseLoader := mock_pause.NewMockLoader(ctrl)
conf := &config.Config{
AvailableLoggingDrivers: []dockerclient.LoggingDriver{
dockerclient.JSONFileDriver,
Expand All @@ -368,6 +395,7 @@ func TestAWSVPCBlockInstanceMetadataWhenTaskENIIsDisabled(t *testing.T) {
}
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)

mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()
gomock.InOrder(
client.EXPECT().SupportedVersions().Return([]dockerclient.DockerVersion{
dockerclient.Version_1_17,
Expand Down Expand Up @@ -404,6 +432,7 @@ func TestAWSVPCBlockInstanceMetadataWhenTaskENIIsDisabled(t *testing.T) {
cfg: conf,
dockerClient: client,
cniClient: cniClient,
pauseLoader: mockPauseLoader,
credentialProvider: aws_credentials.NewCredentials(mockCredentialsProvider),
mobyPlugins: mockMobyPlugins,
}
Expand Down Expand Up @@ -443,6 +472,9 @@ func TestCapabilitiesExecutionRoleAWSLogs(t *testing.T) {
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
Expand All @@ -451,6 +483,7 @@ func TestCapabilitiesExecutionRoleAWSLogs(t *testing.T) {
cfg: conf,
dockerClient: client,
cniClient: cniClient,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -474,6 +507,8 @@ func TestCapabilitiesTaskResourceLimit(t *testing.T) {
client := mock_dockerapi.NewMockDockerClient(ctrl)
versionList := []dockerclient.DockerVersion{dockerclient.Version_1_22}
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)
mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()
gomock.InOrder(
client.EXPECT().SupportedVersions().Return(versionList),
client.EXPECT().KnownVersions().Return(versionList),
Expand All @@ -488,6 +523,7 @@ func TestCapabilitiesTaskResourceLimit(t *testing.T) {
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -514,6 +550,8 @@ func TestCapabilitesTaskResourceLimitDisabledByMissingDockerVersion(t *testing.T
client := mock_dockerapi.NewMockDockerClient(ctrl)
versionList := []dockerclient.DockerVersion{dockerclient.Version_1_19}
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)
mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()
gomock.InOrder(
client.EXPECT().SupportedVersions().Return(versionList),
client.EXPECT().KnownVersions().Return(versionList),
Expand All @@ -528,6 +566,7 @@ func TestCapabilitesTaskResourceLimitDisabledByMissingDockerVersion(t *testing.T
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -553,6 +592,8 @@ func TestCapabilitesTaskResourceLimitErrorCase(t *testing.T) {

client := mock_dockerapi.NewMockDockerClient(ctrl)
versionList := []dockerclient.DockerVersion{dockerclient.Version_1_19}
mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()
gomock.InOrder(
client.EXPECT().SupportedVersions().Return(versionList),
client.EXPECT().KnownVersions().Return(versionList),
Expand All @@ -563,6 +604,7 @@ func TestCapabilitesTaskResourceLimitErrorCase(t *testing.T) {
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
pauseLoader: mockPauseLoader,
dockerClient: client,
}

Expand All @@ -586,13 +628,17 @@ func TestCapabilitiesContainerHealth(t *testing.T) {
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: &config.Config{},
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand Down Expand Up @@ -623,13 +669,17 @@ func TestCapabilitiesContainerHealthDisabled(t *testing.T) {
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil)

mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: &config.Config{DisableDockerHealthCheck: true},
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -651,6 +701,8 @@ func TestCapabilitesListPluginsErrorCase(t *testing.T) {

client := mock_dockerapi.NewMockDockerClient(ctrl)
versionList := []dockerclient.DockerVersion{dockerclient.Version_1_19}
mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()
gomock.InOrder(
client.EXPECT().SupportedVersions().Return(versionList),
client.EXPECT().KnownVersions().Return(versionList),
Expand All @@ -665,6 +717,7 @@ func TestCapabilitesListPluginsErrorCase(t *testing.T) {
ctx: ctx,
cfg: &config.Config{},
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -685,6 +738,8 @@ func TestCapabilitesScanPluginsErrorCase(t *testing.T) {

client := mock_dockerapi.NewMockDockerClient(ctrl)
versionList := []dockerclient.DockerVersion{dockerclient.Version_1_19}
mockPauseLoader := mock_pause.NewMockLoader(ctrl)
mockPauseLoader.EXPECT().IsLoaded(gomock.Any()).Return(false, nil).AnyTimes()
gomock.InOrder(
client.EXPECT().SupportedVersions().Return(versionList),
client.EXPECT().KnownVersions().Return(versionList),
Expand All @@ -699,6 +754,7 @@ func TestCapabilitesScanPluginsErrorCase(t *testing.T) {
ctx: ctx,
cfg: &config.Config{},
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand Down
5 changes: 5 additions & 0 deletions agent/app/agent_capability_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ func (agent *ecsAgent) appendBranchENIPluginVersionAttribute(capabilities []*ecs
}

func (agent *ecsAgent) appendPIDAndIPCNamespaceSharingCapabilities(capabilities []*ecs.Attribute) []*ecs.Attribute {
isLoaded, err := agent.pauseLoader.IsLoaded(agent.dockerClient)
if !isLoaded || err != nil {
seelog.Warnf("Pause container is not loaded, did not append PID and IPC capabilities: %v", err)
return capabilities
}
return appendNameOnlyAttribute(capabilities, attributePrefix+capabiltyPIDAndIPCNamespaceSharing)
}

Expand Down
Loading

0 comments on commit 69ef247

Please sign in to comment.