-
Notifications
You must be signed in to change notification settings - Fork 613
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
metadata service continued #981
Conversation
2af95e7
to
2feb1fa
Compare
7ac27ba
to
9383f5f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass of review. I'll take another detailed look.
README.md
Outdated
@@ -175,10 +175,16 @@ configure them as something other than the defaults. | |||
| `ECS_IMAGE_MINIMUM_CLEANUP_AGE` | 30m | The minimum time interval between when an image is pulled and when it can be considered for automated image cleanup. | 1h | 1h | | |||
| `ECS_NUM_IMAGES_DELETE_PER_CYCLE` | 5 | The maximum number of images to delete in a single automated image cleanup cycle. If set to less than 1, the value is ignored. | 5 | 5 | | |||
| `ECS_INSTANCE_ATTRIBUTES` | `{"stack": "prod"}` | These attributes take effect only during initial registration. After the agent has joined an ECS cluster, use the PutAttributes API action to add additional attributes. For more information, see [Amazon ECS Container Agent Configuration](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-config.html) in the Amazon ECS Developer Guide.| `{}` | `{}` | | |||
<<<<<<< 6f11735d92bbf1ce7bbe099721a17384095fdff7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a remnant of merge resolution. please get rid of this.
@@ -393,6 +395,8 @@ func environmentConfig() (Config, error) { | |||
CNIPluginsPath: cniPluginsPath, | |||
AWSVPCBlockInstanceMetdata: awsVPCBlockInstanceMetadata, | |||
AWSVPCAdditionalLocalRoutes: additionalLocalRoutes, | |||
ContainerMetadataEnabled: containerMetadataEnabled, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also update DefaultConfig
to set ContainerMetadataEnabled
to false
?
@@ -353,6 +353,8 @@ func environmentConfig() (Config, error) { | |||
errs = append(errs, err) | |||
} | |||
} | |||
containerMetadataEnabled := utils.ParseBool(os.Getenv("ECS_ENABLE_CONTAINER_METADATA"), false) | |||
dataDirOnHost := os.Getenv("ECS_HOST_DATA_DIR") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when ECS Init/whatever's starting the Agent mounts some other directory as Agent's data directory (-v /tmp:/data
) sets ECS_HOST_DATA_DIR
to "/var/lib/ecs"
It doesn't seem like a strong enough abstraction to be dependent on Agent configuration options to expect ECS_HOST_DATA_DIR
to be the same as whatever's being mounted as /data
on the host. My main concern is the late-binding/asynchronous failures this could lead to if the wrong host mount was specified. Wondering if there are better alternatives here. Can we at the very least inspect the Agent container and check if ECS_HOST_DATA_DIR
is mounted? If the answer is that we'll revisit the validation here at some latter stage, that's fine too. But, I want us to be aware of potential failures here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can get rid of ECS_HOST_DATA_DIR
if we directly inspect the Agent container for whichever directory is mounted as /data
and pass that into the metadata methods wherever appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaithal hm you're right, there's a failure case here. i agree it makes sense to validate ECS_HOST_DATA_DIR is mounted by inspecting the Agent container.
however, i'm not sure if it makes more sense to fail during agent creation with a configuration error since the user will be expecting the metadata feature to be enabled, or if it would make more sense for us to surface a warning log and just disable the metadata feature.
i think failing explicitly during agent creation, newAgent(...)
, makes more sense since this would be a configuration error. whereas logging, disabling the feature and moving forward seems like a poor experience since the only ways for the user to find out about these errors would be to catch it in the log, or through containers failing because they expect a metadata file.
or do you have a more sensible way to communicate this error to the user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think failing explicitly during agent creation, newAgent(...), makes more sense since this would be a configuration error.
I agree
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaithal so as per our discussion earlier, we will call this out in the README under usage instructions for the metadata feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few assumptions here that I think are problematic:
- Assuming that
ECS_HOST_DATA_DIR
is/var/lib/ecs
on the host - Assuming that the ECS agent is running inside a container (it runs outside a container on Windows)
- Assuming that the ECS agent container has the name
ecs-agent
so you can inspect the container (true on ECS-optimized AMIs and other places whereecs-init
is used, but not elsewhere) - Assuming that you can get the ECS agent container ID through its hostname so you can inspect the container (won't be true if the UTS namespace is shared)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding to samuelkarp's second point, I believe the metadata feature does not work when the agent is run outside a container on Linux environments. Initially I was told this is a minor concern, but do we have use cases for the agent being run outside a container on Linux? For Windows, this situation is explicitly handled (As noted in the current documentation).
agent/containermetadata/types.go
Outdated
// Network is a struct that keeps track of metadata of a network interface | ||
type Network struct { | ||
NetworkMode string `json:"NetworkMode,omitempty"` | ||
IPv4Address string `json:"IPv4Address,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to IPv4Addresses
instead? For now it can be a list of length 1. It'd be helpful to surface this info when we start containers with multiple IP addresses.
agent/containermetadata/types.go
Outdated
type Network struct { | ||
NetworkMode string `json:"NetworkMode,omitempty"` | ||
IPv4Address string `json:"IPv4Address,omitempty"` | ||
IPv6Address string `json:"IPv6Address,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. Can you change this to IPv6Addresses
instead ([]string
)?
"name": "mdservice-validator-unix", | ||
"cpu": 10, | ||
"memory": 10, | ||
"command": ["sh", "-c", "sleep 1 && if cat $ECS_CONTAINER_METADATA_FILE | grep \"READY\"; then exit 42; else exit 1; fi"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sleep 1
may not always be sufficient. Can you increase this duration to something like 10s
? Or, you can check for the existence in a loop and poll on the file for a maximum of 1m
.
README.md
Outdated
@@ -175,10 +175,16 @@ configure them as something other than the defaults. | |||
| `ECS_IMAGE_MINIMUM_CLEANUP_AGE` | 30m | The minimum time interval between when an image is pulled and when it can be considered for automated image cleanup. | 1h | 1h | | |||
| `ECS_NUM_IMAGES_DELETE_PER_CYCLE` | 5 | The maximum number of images to delete in a single automated image cleanup cycle. If set to less than 1, the value is ignored. | 5 | 5 | | |||
| `ECS_INSTANCE_ATTRIBUTES` | `{"stack": "prod"}` | These attributes take effect only during initial registration. After the agent has joined an ECS cluster, use the PutAttributes API action to add additional attributes. For more information, see [Amazon ECS Container Agent Configuration](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-config.html) in the Amazon ECS Developer Guide.| `{}` | `{}` | | |||
<<<<<<< 6f11735d92bbf1ce7bbe099721a17384095fdff7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a merge conflict not fixed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
README.md
Outdated
| `ECS_ENABLE_TASK_ENI` | `false` | Whether to enable task networking for task to be launched with its own network interface | `false` | Not applicable | | ||
| `ECS_CNI_PLUGINS_PATH` | `/ecs/cni` | The path where the cni binary file is located | `/amazon-ecs-cni-plugins` | Not applicable | | ||
| `ECS_AWSVPC_BLOCK_IMDS` | `true` | Whether to block access to [Instance Metdata](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) for Tasks started with `awsvpc` network mode | `false` | Not applicable | | ||
| `ECS_AWSVPC_ADDITIONAL_LOCAL_ROUTES` | `["10.0.15.0/24"]` | In `awsvpc` network mode, traffic to these prefixes will be routed via the host bridge instead of the task ENI | `[]` | Not applicable | | ||
| `ECS_ENABLE_TASK_ENI` | `false` | Whether to enable task networking for task to be launched with its own network interface | `false` | `false` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this appeared in this pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ugh it's related to your last comment, left over from merge resolution. fixed.
agent/api/container.go
Outdated
@@ -112,6 +112,10 @@ type Container struct { | |||
// handled properly so that the state storage continues to work. | |||
SentStatusUnsafe ContainerStatus `json:"SentStatus"` | |||
|
|||
// MetadataUpdated is set to true when we have completed updating the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: MetadataFileUpdated
agent/containermetadata/manager.go
Outdated
// starts up | ||
// In the future the metadata may require multiple stages of update and these | ||
// statuses should amended/appended accordingly. | ||
type MetadataStatus string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use enum type like the container/task status?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this was a section I wrote and the reason I used a string rather than enum was to display the actual name of the status in the JSON Marshaling. Not quite certain but using an enum would produce numerical codes in the Marshaled output, which I think is less helpful to users checking for this status.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can still have status names in marshaled JSON output with iotas (Go doesn't actually have enums), but you'd need to implement the TextMarshaler
and TextUnmarshaler
interfaces.
I would recommend doing this, as you then get stronger assurances about what will be marshaled/unmarshaled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adnxn can you address @samuelkarp's comment as well? Also, can this be moved to containermetadata/types.go
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gotcha, fixed. using iotas and moved to containermetadata/types.go
.
agent/containermetadata/manager.go
Outdated
|
||
"github.com/aws/amazon-ecs-agent/agent/config" | ||
"github.com/aws/amazon-ecs-agent/agent/utils/ioutilwrapper" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove this blank line
} | ||
} | ||
|
||
// TestClean is the mainline case for metadata create |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you fix this comment, it's not clear to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with the comment below, I wrote this comment intending it to mean "TestClean is the happy path case for metadata file cleanup".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we may want these comments to be more specific to the test, as the current comment doesn't have useful and clear meaning for the test.
"github.com/golang/mock/gomock" | ||
) | ||
|
||
// TestCreate is the mainline case for metadata create |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this comment is reused everywhere, can you fix this? Also please use assert
or require
for this package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
_, err := getTaskIDfromARN(mockTaskARN) | ||
expectErrorMessage := fmt.Sprintf("get task ARN: cannot find TaskID for TaskARN %s", mockTaskARN) | ||
|
||
if err.Error() != expectErrorMessage { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use assert
instead, same for other packages.
agent/engine/default.go
Outdated
@@ -26,6 +27,6 @@ import ( | |||
var log = logger.ForModule("TaskEngine") | |||
|
|||
// NewTaskEngine returns a default TaskEngine | |||
func NewTaskEngine(cfg *config.Config, client DockerClient, credentialsManager credentials.Manager, containerChangeEventStream *eventstream.EventStream, imageManager ImageManager, state dockerstate.TaskEngineState) TaskEngine { | |||
return NewDockerTaskEngine(cfg, client, credentialsManager, containerChangeEventStream, imageManager, state) | |||
func NewTaskEngine(cfg *config.Config, client DockerClient, credentialsManager credentials.Manager, containerChangeEventStream *eventstream.EventStream, imageManager ImageManager, state dockerstate.TaskEngineState, metadataManager containermetadata.Manager) TaskEngine { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you break this into multiple lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/engine/docker_task_engine.go
Outdated
} | ||
|
||
// NewDockerTaskEngine returns a created, but uninitialized, DockerTaskEngine. | ||
// The distinction between created and initialized is that when created it may | ||
// be serialized/deserialized, but it will not communicate with docker until it | ||
// is also initialized. | ||
func NewDockerTaskEngine(cfg *config.Config, client DockerClient, credentialsManager credentials.Manager, containerChangeEventStream *eventstream.EventStream, imageManager ImageManager, state dockerstate.TaskEngineState) *DockerTaskEngine { | ||
func NewDockerTaskEngine(cfg *config.Config, client DockerClient, credentialsManager credentials.Manager, containerChangeEventStream *eventstream.EventStream, imageManager ImageManager, state dockerstate.TaskEngineState, metadataManager containermetadata.Manager) *DockerTaskEngine { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please break this into multiple lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
558b98a
to
ff162ba
Compare
agent/api/container.go
Outdated
@@ -306,3 +310,17 @@ func (c *Container) IsInternal() bool { | |||
func (c *Container) IsRunning() bool { | |||
return c.GetKnownStatus().IsRunning() | |||
} | |||
|
|||
func (c *Container) IsMetadataFileUpdated() bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint: Please add a comment here for public methods, same for below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
agent/config/config_windows.go
Outdated
@@ -59,7 +60,9 @@ func DefaultConfig() Config { | |||
netBIOSPort, | |||
}, | |||
ReservedPortsUDP: []uint16{}, | |||
DataDir: filepath.Join(ecsRoot, "data"), | |||
DataDir: dataDir, | |||
// DataDirOnHost is identical to DataDir for Windows because we do not run on a container |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: run agent as a container
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
if err != nil { | ||
// Retry if file does not exist | ||
if osWrap.IsNotExist(err) { | ||
file, err = osWrap.Create(metadataFileName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to set the file permission after creating?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking at this again, we can remove the retry block with osWrap.IsNotExist(err) {...
by changing the open file line to file, err := osWrap.OpenFile(metadataFileName, os.O_WRONLY | os.O_CREATE, metadataPerm)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually nvm. from godocs,
"On Windows, the mode must be non-zero but otherwise only the 0200 bit (owner writable) of mode is used; it controls whether the file's read-only attribute is set or cleared. attribute. The other bits are currently unused. Use mode 0400 for a read-only file and 0600 for a readable+writable file."
so we might not be able to have the exact same permission as we do on linux. i'll follow up with someone on the team that knows more about windows file permissions.
@@ -636,3 +636,27 @@ func fluentdDriverTest(taskDefinition string, t *testing.T) { | |||
err = SearchStrInDir(fluentdLogPath, "ecsfts", logTag) | |||
assert.NoError(t, err, "failed to find the log tag specified in the task definition") | |||
} | |||
|
|||
// TestMetadataServiceValidator Tests that the metadata file can be accessed from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also add this test for windows?
agent/statemanager/state_manager.go
Outdated
@@ -48,6 +48,7 @@ const ( | |||
// b) Add 'ContainerResourcesProvisioned' as a new 'ContainerStatus' enum | |||
// c) Add 'SteadyStateStatus' field to 'Container' struct | |||
// d) Add 'ENIAttachments' struct | |||
// e) Add 'MetadataUpdated' field to 'api.Container' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this should be space instead of tab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/containermetadata/manager.go
Outdated
// statuses should amended/appended accordingly. | ||
type MetadataStatus string | ||
|
||
const ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more of a code structure thing. I like to see consts at the top of the file (you'll find that to be the case in rest of this code base as well). Can you move this block to the top of the file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/engine/docker_task_engine.go
Outdated
if engine.cfg.ContainerMetadataEnabled { | ||
err := engine.metadataManager.Clean(task.Arn) | ||
if err != nil { | ||
seelog.Errorf("Clean task metadata failed for task %s: %v", task, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please change this to a Warn
? I'd prefer Error
to be used if it correlates with a customer facing error, which this is not (Applies to the rest of the file(s) as well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
@adnxn an you investigate why appveyor is failing and resolve merge conflicts as well? |
agent/containermetadata/manager.go
Outdated
// starts up | ||
// In the future the metadata may require multiple stages of update and these | ||
// statuses should amended/appended accordingly. | ||
type MetadataStatus string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adnxn can you address @samuelkarp's comment as well? Also, can this be moved to containermetadata/types.go
?
} | ||
|
||
// Acquire the metadata then write it in JSON format to the file | ||
metadata := manager.parseMetadataAtContainerCreate(taskARN, containerName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic of parsing, marshaling and writing the metadata file is duplicated between this and the Update
method. Please extract that to a method of its own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
// containing the task-id which we extract by splitting it by "/". | ||
// This function should be eventually be replaced by a standardized ARN parsing | ||
// module | ||
func getTaskIDfromARN(taskARN string) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to get rid of this if we use the updated SDK and the arn.Parse()
method from aws/aws-sdk-go@1fb10cf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed. updating sdk here #1006 and added the aws/arn
package to this set of changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not including this change since godep is doing this.
} | ||
metadataFileName := filepath.Join(metadataFileDir, metadataFile) | ||
|
||
temp, err := ioutilWrap.TempFile(metadataFileDir, "temp_metadata_file") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you const "temp_metadata_file"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/engine/docker_task_engine.go
Outdated
if engine.cfg.ContainerMetadataEnabled { | ||
err := engine.metadataManager.Clean(task.Arn) | ||
if err != nil { | ||
seelog.Warnf("Clean task metadata failed for task %s: %v", task, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be task.Arn
. Also, can you add unit tests for sweepTask
and exercise this code path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed the task.Arn
thing. and the existing happy path test exercises that code path.
all @huerdong commits squashed for manageable commit history in PR
This commit is fix gomock version mismatch and regenerate all mocks to fix breaking builds with metadata service changes
This change adds logic in the agent to update the metadata file after the agent restarts and the related unit test. Note that we added a MetadataFileUpdated flag in the api.Container struct and this is included with state file's ECSDataVersion 6 bump.
|
||
// Get Port bindings from docker configurations | ||
var ports []api.PortBinding | ||
var err error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: if there's no specific reason to declare this here, can you get rid of it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im going to leave this one as it is, the nested branch needs both, and we return ports even if its empty.
agent/containermetadata/types.go
Outdated
} | ||
|
||
func (status *MetadataStatus) UnmarshalText(text []byte) error { | ||
var err error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can get rid of this line and return nil
at the end of the method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh i see why, fixed.
// statuses should amended/appended accordingly. | ||
type MetadataStatus int32 | ||
|
||
func (status MetadataStatus) MarshalText() (text []byte, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have unit test for this and the unmarshal method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added tests for this.
agent/engine/docker_task_engine.go
Outdated
go func() { | ||
err := engine.metadataManager.Update(dockerContainer.DockerID, task.Arn, container.Name) | ||
if err != nil { | ||
seelog.Warnf("Update metadata file failed for container %s of task %s: %v", container, task, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: you can return
here and get rid of else
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/engine/docker_task_engine.go
Outdated
seelog.Warnf("Update metadata file failed for container %s of task %s: %v", container, task, err) | ||
} else { | ||
container.SetMetadataFileUpdated() | ||
seelog.Debugf("Updated metadata file for container %s of task %s", container, task) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and in the rest of the file, let's log less: task.Arn
, container.Name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gotcha. cleaned up instances of this in the file.
this change also includes minor changes to addresses cr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mostly looks good. I have some minor comments.
agent/statemanager/state_manager.go
Outdated
@@ -49,6 +49,7 @@ const ( | |||
// c) Add 'SteadyStateStatus' field to 'Container' struct | |||
// d) Add 'ENIAttachments' struct | |||
// e) Deprecate 'SteadyStateDependencies' in favor of 'TransitionDependencySet' | |||
// f) Add 'MetadataUpdated' field to 'api.Container' | |||
ECSDataVersion = 6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be 7
now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, fixed.
agent/containermetadata/manager.go
Outdated
) | ||
|
||
const ( | ||
metadataEnvironmentVariable = "ECS_CONTAINER_METADATA_FILE" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add documentation for this variable stating that this will be set in the container's host config and this is what customers would use to locate/access metadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added documentation for ECS_CONTAINER_METADATA_FILE
in the readme, also we should discuss if we need to include more detailed documentation wrt format of the file and the specific fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not including this change in favor of separate docs pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not? You can still document what this variable does // metadataEnvironmentVariable is ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i didn't realise you meant in the code earlier. fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didnt realise you meant document in the code earlier. fixed now.
agent/containermetadata/manager.go
Outdated
|
||
// Acquire the metadata then write it in JSON format to the file | ||
metadata := manager.parseMetadata(dockerContainer, taskARN, containerName) | ||
err = manager.marshalAndWrite(metadata, taskARN, containerName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: if you aren't doing anything with the error returned, you can just do return manager.marshalAndWrite(metadata, taskARN, containerName)
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense, fixed.
agent/containermetadata/manager.go
Outdated
func (manager *metadataManager) Clean(taskARN string) error { | ||
metadataPath, err := getTaskMetadataDir(taskARN, manager.dataDir) | ||
if err != nil { | ||
return fmt.Errorf("clean task %s: %v", taskARN, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add more context here: "clean task metadata: unable to get metadata directory for task %s: %v"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/containermetadata/manager.go
Outdated
func (manager *metadataManager) marshalAndWrite(metadata Metadata, taskARN string, containerName string) error { | ||
data, err := json.MarshalIndent(metadata, "", "\t") | ||
if err != nil { | ||
return fmt.Errorf("create metadata for task %s container %s: %v", taskARN, containerName, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, needs more context: "create metadata for container %s in task %s: failed to marshal metadata"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/containermetadata/manager.go
Outdated
} | ||
|
||
// Write the metadata to file | ||
err = writeToMetadataFile(manager.osWrap, manager.ioutilWrap, data, taskARN, containerName, manager.dataDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here too, you could just do return writeMetadata...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense, fixed.
unit tests no manager_test.go no longer depend on error message format.
README.md
Outdated
@@ -181,6 +181,9 @@ configure them as something other than the defaults. | |||
| `ECS_AWSVPC_ADDITIONAL_LOCAL_ROUTES` | `["10.0.15.0/24"]` | In `awsvpc` network mode, traffic to these prefixes will be routed via the host bridge instead of the task ENI | `[]` | Not applicable | | |||
| `ECS_ENABLE_CONTAINER_METADATA` | `<true|false>` | Whether to enable creation of a metadata file in the containers. If enabled the agent will inject a file with the container's various metadata and the user can access the container's metadata internally by accessing the environment variable $ECS_CONTAINER_METADATA_FILE. | `false` | `false` | | |||
| `ECS_HOST_DATA_DIR` | `/var/lib/ecs` | The source directory on the host from which ECS_DATADIR is mounted. We use this to determine the source mount path for container metadata files in the case the Agent is run in a container. We do not use this value in Windows because the Agent is not run on a container in Windows. | `/var/lib/ecs` | `Not used` | | |||
| `ECS_CONTAINER_METADATA_FILE` | set by the agent | This is variable is set in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to document this in README.md. The variables we have here are the Agent config settings used to tune the Agent. It may make sense to add an example at the end of the readme or something demonstrating how to use the metadata feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, i'll add a separate section for this altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not including this change in favor of separate docs pr
ee953a1
to
347977d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM except minor comments
README.md
Outdated
@@ -179,6 +179,8 @@ configure them as something other than the defaults. | |||
| `ECS_CNI_PLUGINS_PATH` | `/ecs/cni` | The path where the cni binary file is located | `/amazon-ecs-cni-plugins` | Not applicable | | |||
| `ECS_AWSVPC_BLOCK_IMDS` | `true` | Whether to block access to [Instance Metdata](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) for Tasks started with `awsvpc` network mode | `false` | Not applicable | | |||
| `ECS_AWSVPC_ADDITIONAL_LOCAL_ROUTES` | `["10.0.15.0/24"]` | In `awsvpc` network mode, traffic to these prefixes will be routed via the host bridge instead of the task ENI | `[]` | Not applicable | | |||
| `ECS_ENABLE_CONTAINER_METADATA` | `true` | When `true`, the agent will create a file describing the container's metadata and the file can be located and consumed by using the container enviornment variable `$ECS_CONTAINER_METADATA_FILE` | `false` | `false` | | |||
| `ECS_HOST_DATA_DIR` | `/var/lib/ecs` | The source directory on the host from which ECS_DATADIR is mounted. We use this to determine the source mount path for container metadata files in the case the Agent is run in a container. We do not use this value in Windows because the Agent is not run on a container in Windows. | `/var/lib/ecs` | `Not used` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: in the case the ECS Agent is running as a container xxxxx because the ECS Agent is not running as a container
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
agent/api/container.go
Outdated
@@ -317,3 +321,20 @@ func (c *Container) IsInternal() bool { | |||
func (c *Container) IsRunning() bool { | |||
return c.GetKnownStatus().IsRunning() | |||
} | |||
|
|||
// IsMetadataFileUpdated() returns true if the metadata file has been once the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you get rid of the parenthesis in the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep gone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 📦 🚀
Summary
carried over work from #913 with following additions:
Implementation details
n/a
Testing
make release
)go build -out amazon-ecs-agent.exe ./agent
)make test
) passgo test -timeout=25s ./agent/...
) passmake run-integ-tests
) pass.\scripts\run-integ-tests.ps1
) passmake run-functional-tests
) pass.\scripts\run-functional-tests.ps1
) passNew tests cover the changes:
Description for the changelog
Licensing
This contribution is under the terms of the Apache 2.0 License: