Skip to content

Commit

Permalink
Fixing Agent reports incorrect capabilities on windows (#2035)
Browse files Browse the repository at this point in the history
  • Loading branch information
mssrivas committed Jun 6, 2019
1 parent 7e0c85a commit 453fb8f
Show file tree
Hide file tree
Showing 7 changed files with 407 additions and 29 deletions.
19 changes: 9 additions & 10 deletions agent/app/agent_capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ func (agent *ecsAgent) capabilities() ([]*ecs.Attribute, error) {

capabilities = agent.appendTaskENICapabilities(capabilities)
capabilities = agent.appendENITrunkingCapabilities(capabilities)

capabilities = agent.appendDockerDependentCapabilities(capabilities, supportedVersions)

// TODO: gate this on docker api version when ecs supported docker includes
Expand All @@ -140,10 +139,6 @@ func (agent *ecsAgent) capabilities() ([]*ecs.Attribute, error) {
// ecs agent version 1.27.0 supports ecs secrets for logging drivers
capabilities = appendNameOnlyAttribute(capabilities, attributePrefix+capabilitySecretLogDriverSSM)

// ecs agent version 1.22.0 supports sharing PID namespaces and IPC resource namespaces
// with host EC2 instance and among containers within the task
capabilities = appendNameOnlyAttribute(capabilities, attributePrefix+capabiltyPIDAndIPCNamespaceSharing)

if agent.cfg.GPUSupportEnabled {
capabilities = agent.appendNvidiaDriverVersionAttribute(capabilities)
}
Expand All @@ -156,14 +151,18 @@ func (agent *ecsAgent) capabilities() ([]*ecs.Attribute, error) {
// ecs agent version 1.27.0 supports ecs secrets for logging drivers
capabilities = appendNameOnlyAttribute(capabilities, attributePrefix+capabilitySecretLogDriverASM)

// support container ordering in agent
capabilities = appendNameOnlyAttribute(capabilities, attributePrefix+capabilityContainerOrdering)

// ecs agent version 1.22.0 supports sharing PID namespaces and IPC resource namespaces
// with host EC2 instance and among containers within the task
capabilities = agent.appendPIDAndIPCNamespaceSharingCapabilities(capabilities)

// ecs agent version 1.26.0 supports aws-appmesh cni plugin
capabilities = appendNameOnlyAttribute(capabilities, attributePrefix+appMeshAttributeSuffix)
capabilities = agent.appendAppMeshCapabilities(capabilities)

// support elastic inference in agent
capabilities = appendNameOnlyAttribute(capabilities, attributePrefix+taskEIAAttributeSuffix)

// support container ordering in agent
capabilities = appendNameOnlyAttribute(capabilities, attributePrefix+capabilityContainerOrdering)
capabilities = agent.appendTaskEIACapabilities(capabilities)

return capabilities, nil
}
Expand Down
9 changes: 0 additions & 9 deletions agent/app/agent_capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ func TestCapabilities(t *testing.T) {
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
{
Name: aws.String(attributePrefix + capabiltyPIDAndIPCNamespaceSharing),
},
{
Name: aws.String(attributePrefix + capabilityECREndpoint),
},
Expand All @@ -129,12 +126,6 @@ func TestCapabilities(t *testing.T) {
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverASM),
},
{
Name: aws.String(attributePrefix + appMeshAttributeSuffix),
},
{
Name: aws.String(attributePrefix + taskEIAAttributeSuffix),
},
{
Name: aws.String(attributePrefix + capabilityContainerOrdering),
},
Expand Down
12 changes: 12 additions & 0 deletions agent/app/agent_capability_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,15 @@ func (agent *ecsAgent) appendBranchENIPluginVersionAttribute(capabilities []*ecs
Value: aws.String(version),
})
}

func (agent *ecsAgent) appendPIDAndIPCNamespaceSharingCapabilities(capabilities []*ecs.Attribute) []*ecs.Attribute {
return appendNameOnlyAttribute(capabilities, attributePrefix+capabiltyPIDAndIPCNamespaceSharing)
}

func (agent *ecsAgent) appendAppMeshCapabilities(capabilities []*ecs.Attribute) []*ecs.Attribute {
return appendNameOnlyAttribute(capabilities, attributePrefix+appMeshAttributeSuffix)
}

func (agent *ecsAgent) appendTaskEIACapabilities(capabilities []*ecs.Attribute) []*ecs.Attribute {
return appendNameOnlyAttribute(capabilities, attributePrefix+taskEIAAttributeSuffix)
}
263 changes: 253 additions & 10 deletions agent/app/agent_capability_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,6 @@ func TestNvidiaDriverCapabilitiesUnix(t *testing.T) {
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
{
Name: aws.String(attributePrefix + capabiltyPIDAndIPCNamespaceSharing),
},
// nvidia driver version capability
{
Name: aws.String(attributePrefix + "nvidia-driver-version.396.44"),
Expand Down Expand Up @@ -270,9 +267,6 @@ func TestEmptyNvidiaDriverCapabilitiesUnix(t *testing.T) {
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
{
Name: aws.String(attributePrefix + capabiltyPIDAndIPCNamespaceSharing),
},
}...)

ctx, cancel := context.WithCancel(context.TODO())
Expand Down Expand Up @@ -363,9 +357,6 @@ func TestENITrunkingCapabilitiesUnix(t *testing.T) {
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
{
Name: aws.String(attributePrefix + capabiltyPIDAndIPCNamespaceSharing),
},
}...)

ctx, cancel := context.WithCancel(context.TODO())
Expand Down Expand Up @@ -444,19 +435,183 @@ func TestNoENITrunkingCapabilitiesUnix(t *testing.T) {
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
}...)

ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
cniClient: cniClient,
credentialProvider: aws_credentials.NewCredentials(mockCredentialsProvider),
mobyPlugins: mockMobyPlugins,
}
capabilities, err := agent.capabilities()
assert.NoError(t, err)

for i, expected := range expectedCapabilities {
assert.Equal(t, aws.StringValue(expected.Name), aws.StringValue(capabilities[i].Name))
assert.Equal(t, aws.StringValue(expected.Value), aws.StringValue(capabilities[i].Value))
}
}

func TestPIDAndIPCNamespaceSharingCapabilitiesUnix(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

client := mock_dockerapi.NewMockDockerClient(ctrl)
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)
mockCredentialsProvider := app_mocks.NewMockProvider(ctrl)
conf := &config.Config{
PrivilegedDisabled: true,
}

gomock.InOrder(
client.EXPECT().SupportedVersions().Return([]dockerclient.DockerVersion{
dockerclient.Version_1_17,
}),
client.EXPECT().KnownVersions().Return([]dockerclient.DockerVersion{
dockerclient.Version_1_17,
}),
mockMobyPlugins.EXPECT().Scan().AnyTimes().Return([]string{}, nil),
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil),
)

expectedCapabilityNames := []string{
"com.amazonaws.ecs.capability.docker-remote-api.1.17",
}

var expectedCapabilities []*ecs.Attribute
for _, name := range expectedCapabilityNames {
expectedCapabilities = append(expectedCapabilities,
&ecs.Attribute{Name: aws.String(name)})
}
expectedCapabilities = append(expectedCapabilities,
[]*ecs.Attribute{
// linux specific capabilities
{
Name: aws.String("ecs.capability.docker-plugin.local"),
},
{
Name: aws.String(attributePrefix + capabilityPrivateRegistryAuthASM),
},
{
Name: aws.String(attributePrefix + capabilitySecretEnvSSM),
},
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
{
Name: aws.String(attributePrefix + capabilityECREndpoint),
},
{
Name: aws.String(attributePrefix + capabilitySecretEnvASM),
},
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverASM),
},
{
Name: aws.String(attributePrefix + capabilityContainerOrdering),
},
{
Name: aws.String(attributePrefix + capabiltyPIDAndIPCNamespaceSharing),
},
}...)
ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
credentialProvider: aws_credentials.NewCredentials(mockCredentialsProvider),
mobyPlugins: mockMobyPlugins,
}
capabilities, err := agent.capabilities()
assert.NoError(t, err)

for i, expected := range expectedCapabilities {
assert.Equal(t, aws.StringValue(expected.Name), aws.StringValue(capabilities[i].Name))
assert.Equal(t, aws.StringValue(expected.Value), aws.StringValue(capabilities[i].Value))
}
}

func TestAppMeshCapabilitiesUnix(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

client := mock_dockerapi.NewMockDockerClient(ctrl)
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)
mockCredentialsProvider := app_mocks.NewMockProvider(ctrl)
conf := &config.Config{
PrivilegedDisabled: true,
}

gomock.InOrder(
client.EXPECT().SupportedVersions().Return([]dockerclient.DockerVersion{
dockerclient.Version_1_17,
}),
client.EXPECT().KnownVersions().Return([]dockerclient.DockerVersion{
dockerclient.Version_1_17,
}),
mockMobyPlugins.EXPECT().Scan().AnyTimes().Return([]string{}, nil),
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil),
)

expectedCapabilityNames := []string{
"com.amazonaws.ecs.capability.docker-remote-api.1.17",
}

var expectedCapabilities []*ecs.Attribute
for _, name := range expectedCapabilityNames {
expectedCapabilities = append(expectedCapabilities,
&ecs.Attribute{Name: aws.String(name)})
}
expectedCapabilities = append(expectedCapabilities,
[]*ecs.Attribute{
// linux specific capabilities
{
Name: aws.String("ecs.capability.docker-plugin.local"),
},
{
Name: aws.String(attributePrefix + capabilityPrivateRegistryAuthASM),
},
{
Name: aws.String(attributePrefix + capabilitySecretEnvSSM),
},
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
{
Name: aws.String(attributePrefix + capabilityECREndpoint),
},
{
Name: aws.String(attributePrefix + capabilitySecretEnvASM),
},
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverASM),
},
{
Name: aws.String(attributePrefix + capabilityContainerOrdering),
},
{
Name: aws.String(attributePrefix + capabiltyPIDAndIPCNamespaceSharing),
},
{
Name: aws.String(attributePrefix + appMeshAttributeSuffix),
},
}...)
ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
cniClient: cniClient,
credentialProvider: aws_credentials.NewCredentials(mockCredentialsProvider),
mobyPlugins: mockMobyPlugins,
}
Expand All @@ -468,3 +623,91 @@ func TestNoENITrunkingCapabilitiesUnix(t *testing.T) {
assert.Equal(t, aws.StringValue(expected.Value), aws.StringValue(capabilities[i].Value))
}
}

func TestTaskEIACapabilitiesUnix(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

client := mock_dockerapi.NewMockDockerClient(ctrl)
mockMobyPlugins := mock_mobypkgwrapper.NewMockPlugins(ctrl)
mockCredentialsProvider := app_mocks.NewMockProvider(ctrl)
conf := &config.Config{
PrivilegedDisabled: true,
}

gomock.InOrder(
client.EXPECT().SupportedVersions().Return([]dockerclient.DockerVersion{
dockerclient.Version_1_17,
}),
client.EXPECT().KnownVersions().Return([]dockerclient.DockerVersion{
dockerclient.Version_1_17,
}),
mockMobyPlugins.EXPECT().Scan().AnyTimes().Return([]string{}, nil),
client.EXPECT().ListPluginsWithFilters(gomock.Any(), gomock.Any(), gomock.Any(),
gomock.Any()).AnyTimes().Return([]string{}, nil),
)

expectedCapabilityNames := []string{
"com.amazonaws.ecs.capability.docker-remote-api.1.17",
}

var expectedCapabilities []*ecs.Attribute
for _, name := range expectedCapabilityNames {
expectedCapabilities = append(expectedCapabilities,
&ecs.Attribute{Name: aws.String(name)})
}
expectedCapabilities = append(expectedCapabilities,
[]*ecs.Attribute{
// linux specific capabilities
{
Name: aws.String("ecs.capability.docker-plugin.local"),
},
{
Name: aws.String(attributePrefix + capabilityPrivateRegistryAuthASM),
},
{
Name: aws.String(attributePrefix + capabilitySecretEnvSSM),
},
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverSSM),
},
{
Name: aws.String(attributePrefix + capabilityECREndpoint),
},
{
Name: aws.String(attributePrefix + capabilitySecretEnvASM),
},
{
Name: aws.String(attributePrefix + capabilitySecretLogDriverASM),
},
{
Name: aws.String(attributePrefix + capabilityContainerOrdering),
},
{
Name: aws.String(attributePrefix + capabiltyPIDAndIPCNamespaceSharing),
},
{
Name: aws.String(attributePrefix + appMeshAttributeSuffix),
},
{
Name: aws.String(attributePrefix + taskEIAAttributeSuffix),
},
}...)
ctx, cancel := context.WithCancel(context.TODO())
// Cancel the context to cancel async routines
defer cancel()
agent := &ecsAgent{
ctx: ctx,
cfg: conf,
dockerClient: client,
credentialProvider: aws_credentials.NewCredentials(mockCredentialsProvider),
mobyPlugins: mockMobyPlugins,
}
capabilities, err := agent.capabilities()
assert.NoError(t, err)

for i, expected := range expectedCapabilities {
assert.Equal(t, aws.StringValue(expected.Name), aws.StringValue(capabilities[i].Name))
assert.Equal(t, aws.StringValue(expected.Value), aws.StringValue(capabilities[i].Value))
}
}
Loading

0 comments on commit 453fb8f

Please sign in to comment.