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 [aws#2290](aws#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 2a60a26
Show file tree
Hide file tree
Showing 14 changed files with 421 additions and 12 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
55 changes: 55 additions & 0 deletions agent/app/agent_capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package app

import (
"errors"
mock_pause "github.com/aws/amazon-ecs-agent/agent/eni/pause/mocks"
"strings"
"testing"

Expand Down Expand Up @@ -46,6 +47,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 +63,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 +146,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 +174,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 +220,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 +263,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 +307,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 +351,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 +384,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 +394,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 +431,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 +471,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 +482,7 @@ func TestCapabilitiesExecutionRoleAWSLogs(t *testing.T) {
cfg: conf,
dockerClient: client,
cniClient: cniClient,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -474,6 +506,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 +522,7 @@ func TestCapabilitiesTaskResourceLimit(t *testing.T) {
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -514,6 +549,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 +565,7 @@ func TestCapabilitesTaskResourceLimitDisabledByMissingDockerVersion(t *testing.T
ctx: ctx,
cfg: conf,
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -553,6 +591,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 +603,7 @@ func TestCapabilitesTaskResourceLimitErrorCase(t *testing.T) {
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
pauseLoader: mockPauseLoader,
dockerClient: client,
}

Expand All @@ -586,13 +627,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)

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 +668,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)

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 +700,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)
gomock.InOrder(
client.EXPECT().SupportedVersions().Return(versionList),
client.EXPECT().KnownVersions().Return(versionList),
Expand All @@ -665,6 +716,7 @@ func TestCapabilitesListPluginsErrorCase(t *testing.T) {
ctx: ctx,
cfg: &config.Config{},
dockerClient: client,
pauseLoader: mockPauseLoader,
mobyPlugins: mockMobyPlugins,
}

Expand All @@ -685,6 +737,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)
gomock.InOrder(
client.EXPECT().SupportedVersions().Return(versionList),
client.EXPECT().KnownVersions().Return(versionList),
Expand All @@ -699,6 +753,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 2a60a26

Please sign in to comment.