Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TMDEv4 changes for service lens #2623

Merged
merged 3 commits into from
Sep 22, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions agent/acs/model/api/api-2.json
Original file line number Diff line number Diff line change
@@ -229,7 +229,8 @@
"dependsOn":{"shape":"ContainerDependencies"},
"startTimeout":{"shape":"Integer"},
"stopTimeout":{"shape":"Integer"},
"firelensConfiguration":{"shape":"FirelensConfiguration"}
"firelensConfiguration":{"shape":"FirelensConfiguration"},
"containerArn":{"shape":"String"}
}
},
"ContainerCondition":{
@@ -682,7 +683,8 @@
"associations":{"shape":"Associations"},
"pidMode":{"shape":"String"},
"ipcMode":{"shape":"String"},
"proxyConfiguration":{"shape":"ProxyConfiguration"}
"proxyConfiguration":{"shape":"ProxyConfiguration"},
"launchType":{"shape":"String"}
}
},
"TaskList":{
4 changes: 4 additions & 0 deletions agent/acs/model/ecsacs/api.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 25 additions & 2 deletions agent/api/container/container.go
Original file line number Diff line number Diff line change
@@ -266,6 +266,9 @@ type Container struct {
// the JSON body while saving the state
SteadyStateStatusUnsafe *apicontainerstatus.ContainerStatus `json:"SteadyStateStatus,omitempty"`

// ContainerArn is the Arn of this container.
ContainerArn string `json:"ContainerArn,omitempty"`

createdAt time.Time
startedAt time.Time
finishedAt time.Time
@@ -1072,13 +1075,33 @@ func (c *Container) GetLogDriver() string {
hostConfig := &dockercontainer.HostConfig{}
err := json.Unmarshal([]byte(*c.DockerConfig.HostConfig), hostConfig)
if err != nil {
seelog.Warnf("Encountered error when trying to get log driver for container %s: %v", err)
seelog.Warnf("Encountered error when trying to get log driver for container %s: %v", c.RuntimeID, err)
return ""
}

return hostConfig.LogConfig.Type
}

// GetLogOptions gets the log 'options' map passed into the task definition.
// see https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LogConfiguration.html
func (c *Container) GetLogOptions() map[string]string {
c.lock.RLock()
defer c.lock.RUnlock()

if c.DockerConfig.HostConfig == nil {
return map[string]string{}
}

hostConfig := &dockercontainer.HostConfig{}
err := json.Unmarshal([]byte(*c.DockerConfig.HostConfig), hostConfig)
if err != nil {
seelog.Warnf("Encountered error when trying to get log configuration for container %s: %v", c.RuntimeID, err)
return map[string]string{}
}

return hostConfig.LogConfig.Config
}

// GetNetworkModeFromHostConfig returns the network mode used by the container from the host config .
func (c *Container) GetNetworkModeFromHostConfig() string {
c.lock.RLock()
@@ -1092,7 +1115,7 @@ func (c *Container) GetNetworkModeFromHostConfig() string {
// TODO return error to differentiate between error and default mode .
err := json.Unmarshal([]byte(*c.DockerConfig.HostConfig), hostConfig)
if err != nil {
seelog.Warnf("Encountered error when trying to get network mode for container %s: %v", err)
seelog.Warnf("Encountered error when trying to get network mode for container %s: %v", c.RuntimeID, err)
return ""
}

3 changes: 3 additions & 0 deletions agent/api/task/task.go
Original file line number Diff line number Diff line change
@@ -259,6 +259,9 @@ type Task struct {
// have a value for this). This field should be accessed via GetLocalIPAddress and SetLocalIPAddress.
LocalIPAddressUnsafe string `json:"LocalIPAddress,omitempty"`

// LaunchType is the launch type of this task.
LaunchType string `json:"LaunchType,omitempty"`

// lock is for protecting all fields in the task struct
lock sync.RWMutex
}
75 changes: 70 additions & 5 deletions agent/handlers/task_server_setup_test.go
Original file line number Diff line number Diff line change
@@ -130,6 +130,7 @@ var (
PullStartedAtUnsafe: now,
PullStoppedAtUnsafe: now,
ExecutionStoppedAtUnsafe: now,
LaunchType: "EC2",
}
container = &apicontainer.Container{
Name: containerName,
@@ -140,6 +141,7 @@ var (
CPU: cpu,
Memory: memory,
Type: apicontainer.ContainerNormal,
ContainerArn: "arn:aws:ecs:ap-northnorth-1:NNN:container/NNNNNNNN-aaaa-4444-bbbb-00000000000",
KnownPortBindingsUnsafe: []apicontainer.PortBinding{
{
ContainerPort: containerPort,
@@ -220,6 +222,7 @@ var (
PullStartedAtUnsafe: now,
PullStoppedAtUnsafe: now,
ExecutionStoppedAtUnsafe: now,
LaunchType: "EC2",
}
container1 = &apicontainer.Container{
Name: containerName,
@@ -297,7 +300,35 @@ var (
}
attachmentIndexVar = attachmentIndex
expectedV4ContainerResponse = v4.ContainerResponse{
ContainerResponse: &expectedContainerResponse,
ContainerResponse: &v2.ContainerResponse{
ID: containerID,
Name: containerName,
DockerName: containerName,
Image: imageName,
ImageID: imageID,
DesiredStatus: statusRunning,
KnownStatus: statusRunning,
ContainerARN: "arn:aws:ecs:ap-northnorth-1:NNN:container/NNNNNNNN-aaaa-4444-bbbb-00000000000",
Limits: v2.LimitsResponse{
CPU: aws.Float64(cpu),
Memory: aws.Int64(memory),
},
Type: containerType,
Labels: labels,
Ports: []v1.PortResponse{
{
ContainerPort: containerPort,
Protocol: containerPortProtocol,
HostPort: containerPort,
},
},
Networks: []containermetadata.Network{
{
NetworkMode: utils.NetworkModeAWSVPC,
IPv4Addresses: []string{eniIPv4Address},
},
},
},
Networks: []v4.Network{{
Network: containermetadata.Network{
NetworkMode: utils.NetworkModeAWSVPC,
@@ -313,8 +344,25 @@ var (
},
}
expectedV4TaskResponse = v4.TaskResponse{
TaskResponse: &expectedTaskResponse,
Containers: []v4.ContainerResponse{expectedV4ContainerResponse},
TaskResponse: &v2.TaskResponse{
Cluster: clusterName,
TaskARN: taskARN,
Family: family,
Revision: version,
DesiredStatus: statusRunning,
KnownStatus: statusRunning,
Containers: []v2.ContainerResponse{expectedContainerResponse},
Limits: &v2.LimitsResponse{
CPU: aws.Float64(cpu),
Memory: aws.Int64(memory),
},
PullStartedAt: aws.Time(now.UTC()),
PullStoppedAt: aws.Time(now.UTC()),
ExecutionStoppedAt: aws.Time(now.UTC()),
AvailabilityZone: availabilityzone,
LaunchType: "EC2",
},
Containers: []v4.ContainerResponse{expectedV4ContainerResponse},
}
expectedV4BridgeContainerResponse = v4.ContainerResponse{
ContainerResponse: &expectedBridgeContainerResponse,
@@ -333,8 +381,25 @@ var (
},
}
expectedV4BridgeTaskResponse = v4.TaskResponse{
TaskResponse: &expectedBridgeTaskResponse,
Containers: []v4.ContainerResponse{expectedV4BridgeContainerResponse},
TaskResponse: &v2.TaskResponse{
Cluster: clusterName,
TaskARN: taskARN,
Family: family,
Revision: version,
DesiredStatus: statusRunning,
KnownStatus: statusRunning,
Containers: []v2.ContainerResponse{expectedBridgeContainerResponse},
Limits: &v2.LimitsResponse{
CPU: aws.Float64(cpu),
Memory: aws.Int64(memory),
},
PullStartedAt: aws.Time(now.UTC()),
PullStoppedAt: aws.Time(now.UTC()),
ExecutionStoppedAt: aws.Time(now.UTC()),
AvailabilityZone: availabilityzone,
LaunchType: "EC2",
},
Containers: []v4.ContainerResponse{expectedV4BridgeContainerResponse},
}
)

39 changes: 31 additions & 8 deletions agent/handlers/v2/response.go
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@ type TaskResponse struct {
AvailabilityZone string `json:"AvailabilityZone,omitempty"`
TaskTags map[string]string `json:"TaskTags,omitempty"`
ContainerInstanceTags map[string]string `json:"ContainerInstanceTags,omitempty"`
LaunchType string `json:"LaunchType,omitempty"`
}

// ContainerResponse defines the schema for the container response
@@ -67,6 +68,9 @@ type ContainerResponse struct {
Networks []containermetadata.Network `json:"Networks,omitempty"`
Health *apicontainer.HealthStatus `json:"Health,omitempty"`
Volumes []v1.VolumeResponse `json:"Volumes,omitempty"`
LogDriver string `json:"LogDriver,omitempty"`
LogOptions map[string]string `json:"LogOptions,omitempty"`
ContainerARN string `json:"ContainerARN,omitempty"`
}

// LimitsResponse defines the schema for task/cpu limits response
@@ -77,13 +81,16 @@ type LimitsResponse struct {
}

// NewTaskResponse creates a new response object for the task
func NewTaskResponse(taskARN string,
func NewTaskResponse(
taskARN string,
state dockerstate.TaskEngineState,
ecsClient api.ECSClient,
cluster string,
az string,
containerInstanceArn string,
propagateTags bool) (*TaskResponse, error) {
propagateTags bool,
includeV4Metadata bool,
) (*TaskResponse, error) {
task, ok := state.TaskByArn(taskARN)
if !ok {
return nil, errors.Errorf("v2 task response: unable to find task '%s'", taskARN)
@@ -98,6 +105,9 @@ func NewTaskResponse(taskARN string,
KnownStatus: task.GetKnownStatus().String(),
AvailabilityZone: az,
}
if includeV4Metadata {
resp.LaunchType = task.LaunchType
}

taskCPU := task.CPU
taskMemory := task.Memory
@@ -129,7 +139,7 @@ func NewTaskResponse(taskARN string,
}

for _, dockerContainer := range containerNameToDockerContainer {
containerResponse := newContainerResponse(dockerContainer, task.GetPrimaryENI(), state)
containerResponse := newContainerResponse(dockerContainer, task.GetPrimaryENI(), state, includeV4Metadata)
resp.Containers = append(resp.Containers, containerResponse)
}

@@ -163,8 +173,11 @@ func propagateTagsToMetadata(state dockerstate.TaskEngineState, ecsClient api.EC
}

// NewContainerResponse creates a new container response based on container id
func NewContainerResponse(containerID string,
state dockerstate.TaskEngineState) (*ContainerResponse, error) {
func NewContainerResponse(
containerID string,
state dockerstate.TaskEngineState,
includeV4Metadata bool,
) (*ContainerResponse, error) {
dockerContainer, ok := state.ContainerByID(containerID)
if !ok {
return nil, errors.Errorf(
@@ -176,13 +189,16 @@ func NewContainerResponse(containerID string,
"v2 container response: unable to find task for container '%s'", containerID)
}

resp := newContainerResponse(dockerContainer, task.GetPrimaryENI(), state)
resp := newContainerResponse(dockerContainer, task.GetPrimaryENI(), state, includeV4Metadata)
return &resp, nil
}

func newContainerResponse(dockerContainer *apicontainer.DockerContainer,
func newContainerResponse(
dockerContainer *apicontainer.DockerContainer,
eni *apieni.ENI,
state dockerstate.TaskEngineState) ContainerResponse {
state dockerstate.TaskEngineState,
includeV4Metadata bool,
) ContainerResponse {
container := dockerContainer.Container
resp := ContainerResponse{
ID: dockerContainer.DockerID,
@@ -200,6 +216,13 @@ func newContainerResponse(dockerContainer *apicontainer.DockerContainer,
ExitCode: container.GetKnownExitCode(),
Labels: container.GetLabels(),
}
// V4 metadata endpoint calls this function for consistency across versions,
// but needs additional metadata only available at this scope.
if includeV4Metadata {
resp.LogDriver = container.GetLogDriver()
resp.LogOptions = container.GetLogOptions()
resp.ContainerARN = container.ContainerArn
}

// Write the container health status inside the container
if dockerContainer.Container.HealthStatusShouldBeReported() {
Loading