From b32ab0754c9c1b82e8c6d67dc095b6ac1e7cb49e Mon Sep 17 00:00:00 2001 From: Yash Kulshrestha Date: Sat, 25 Feb 2023 00:54:08 +0000 Subject: [PATCH 1/3] Release 1.69.0 --- CHANGELOG.md | 10 ++++++++++ VERSION | 2 +- agent/version/version.go | 4 ++-- ecs-init/ECSVERSION | 2 +- ecs-init/config/common.go | 2 +- packaging/amazon-linux-ami-integrated/ecs-agent.spec | 5 ++++- packaging/generic-deb-integrated/debian/changelog | 6 ++++++ packaging/generic-rpm-integrated/amazon-ecs-init.spec | 5 ++++- packaging/suse/amazon-ecs-init.changes | 4 ++++ scripts/changelog/CHANGELOG_MASTER | 5 +++++ 10 files changed, 38 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b63e5aa35..e79c905486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ # Changelog + +## 1.69.0 +* Enhancement - Use T.TempDir to create temporary test directory [#3159](https://github.com/aws/amazon-ecs-agent/pull/3159) and [#3560](https://github.com/aws/amazon-ecs-agent/pull/3560) +* Enhancement - remove set-output GitHub action command [#3487](https://github.com/aws/amazon-ecs-agent/pull/3487) +* Enhancement - periodically disconnect from ACS [#3586](https://github.com/aws/amazon-ecs-agent/pull/3586) +* Bug - Fixed a bug that incorrectly advertised the gMSA and fsx capability [#3540](https://github.com/aws/amazon-ecs-agent/pull/3540) +* Bug - Remove fallback to Docker for host port ranges assignment [#3569](https://github.com/aws/amazon-ecs-agent/pull/3569) +* Bug - fix ecs-init log message [#3577](https://github.com/aws/amazon-ecs-agent/pull/3577) +* Bug - Update CNI plugin versions, IMDS access works properly over IPv6 [#3581](https://github.com/aws/amazon-ecs-agent/pull/3581) + ## 1.68.2 * Enhancement: Skip sending STSC events for internal tasks [#3541](https://github.com/aws/amazon-ecs-agent/pull/3541) and [#3559](https://github.com/aws/amazon-ecs-agent/pull/3559) * Enhancement: Update go version in module file, update most vendored build dependencies to latest library [#3534](https://github.com/aws/amazon-ecs-agent/pull/3534) and [#3551](https://github.com/aws/amazon-ecs-agent/pull/3551) diff --git a/VERSION b/VERSION index 5deab586f9..4934985655 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.68.2 +1.69.0 diff --git a/agent/version/version.go b/agent/version/version.go index 63f2eccf6a..4ca2adcb9e 100644 --- a/agent/version/version.go +++ b/agent/version/version.go @@ -22,10 +22,10 @@ package version // repository. Only the 'Version' const should change in checked-in source code // Version is the version of the Agent -const Version = "1.68.2" +const Version = "1.69.0" // GitDirty indicates the cleanliness of the git repo when this agent was built const GitDirty = true // GitShortHash is the short hash of this agent build -const GitShortHash = "8188bcc0" +const GitShortHash = "0fe21da1" diff --git a/ecs-init/ECSVERSION b/ecs-init/ECSVERSION index 5deab586f9..4934985655 100644 --- a/ecs-init/ECSVERSION +++ b/ecs-init/ECSVERSION @@ -1 +1 @@ -1.68.2 +1.69.0 diff --git a/ecs-init/config/common.go b/ecs-init/config/common.go index 71a06bcfb2..af9cee2430 100644 --- a/ecs-init/config/common.go +++ b/ecs-init/config/common.go @@ -46,7 +46,7 @@ const ( // DefaultAgentVersion is the version of the agent that will be // fetched if required. This should look like v1.2.3 or an // 8-character sha, as is downloadable from S3. - DefaultAgentVersion = "v1.68.2" + DefaultAgentVersion = "v1.69.0" // AgentPartitionBucketName is the name of the paritional s3 bucket that stores the agent AgentPartitionBucketName = "amazon-ecs-agent" diff --git a/packaging/amazon-linux-ami-integrated/ecs-agent.spec b/packaging/amazon-linux-ami-integrated/ecs-agent.spec index 7d5a7d895f..944248e972 100644 --- a/packaging/amazon-linux-ami-integrated/ecs-agent.spec +++ b/packaging/amazon-linux-ami-integrated/ecs-agent.spec @@ -26,7 +26,7 @@ %global agent_image ecs-agent-v%{version}.tar Name: ecs-init -Version: 1.68.2 +Version: 1.69.0 Release: 1%{?dist} License: Apache 2.0 Summary: Amazon Elastic Container Service initialization application @@ -269,6 +269,9 @@ fi %endif %changelog +* Fri Feb 24 2023 Yash Kulshrestha - 1.69.0-1 +- Cache Agent version 1.69.0 + * Wed Feb 08 2023 Prateek Chaudhry - 1.68.2-1 - Cache Agent version 1.68.2 diff --git a/packaging/generic-deb-integrated/debian/changelog b/packaging/generic-deb-integrated/debian/changelog index ed3dce9a6f..c9983ef601 100644 --- a/packaging/generic-deb-integrated/debian/changelog +++ b/packaging/generic-deb-integrated/debian/changelog @@ -1,3 +1,9 @@ +amazon-ecs-init (1.69.0-1) stable; urgency=medium + + * Cache Agent version 1.69.0 + + -- Yash Kulshrestha Fri, 24 Feb 2023 18:00:00 +0000 + amazon-ecs-init (1.68.2-1) stable; urgency=medium * Cache Agent version 1.68.2 diff --git a/packaging/generic-rpm-integrated/amazon-ecs-init.spec b/packaging/generic-rpm-integrated/amazon-ecs-init.spec index aa8480e262..5c03d062c7 100644 --- a/packaging/generic-rpm-integrated/amazon-ecs-init.spec +++ b/packaging/generic-rpm-integrated/amazon-ecs-init.spec @@ -19,7 +19,7 @@ %global agent_image ecs-agent-v%{version}.tar Name: amazon-ecs-init -Version: 1.68.2 +Version: 1.69.0 Release: 1 License: Apache 2.0 Summary: Amazon Elastic Container Service initialization application @@ -92,6 +92,9 @@ ln -sf %{basename:%{agent_image}} %{_cachedir}/ecs/ecs-agent.tar %systemd_postun_with_restart amazon-ecs-volume-plugin %changelog +* Fri Feb 24 2023 Yash Kulshrestha - 1.69.0-1 +- Cache Agent version 1.69.0 + * Wed Feb 08 2023 Prateek Chaudhry - 1.68.2-1 - Cache Agent version 1.68.2 diff --git a/packaging/suse/amazon-ecs-init.changes b/packaging/suse/amazon-ecs-init.changes index 323adde174..b80483aca9 100644 --- a/packaging/suse/amazon-ecs-init.changes +++ b/packaging/suse/amazon-ecs-init.changes @@ -1,4 +1,8 @@ ------------------------------------------------------------------- +Fri Feb 24, 18:00:00 UTC 2023 - kulshres@amazon.com - 1.69.0-1 + +- Cache Agent version 1.69.0 +------------------------------------------------------------------- Wed Feb 08, 18:00:00 UTC 2023 - ptchau@amazon.com - 1.68.2-1 - Cache Agent version 1.68.2 diff --git a/scripts/changelog/CHANGELOG_MASTER b/scripts/changelog/CHANGELOG_MASTER index 3a41cc578f..9d9400a395 100644 --- a/scripts/changelog/CHANGELOG_MASTER +++ b/scripts/changelog/CHANGELOG_MASTER @@ -1,3 +1,8 @@ +1.69.0-1 +Yash Kulshrestha +2023-02-24T10:00:00-08:00 +Cache Agent version 1.69.0 + 1.68.2-1 Prateek Chaudhry 2023-02-08T10:00:00-08:00 From 7600ecfb9e1920eaadd80601e1f6db76a62c1b3d Mon Sep 17 00:00:00 2001 From: Anuj Singh Date: Thu, 23 Feb 2023 19:56:37 -0800 Subject: [PATCH 2/3] fix TestMetricsDisabled --- agent/tcs/client/client_test.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/agent/tcs/client/client_test.go b/agent/tcs/client/client_test.go index 4047ca0476..999068452a 100644 --- a/agent/tcs/client/client_test.go +++ b/agent/tcs/client/client_test.go @@ -23,6 +23,7 @@ package tcsclient import ( + "context" "fmt" "math/rand" "strconv" @@ -36,6 +37,7 @@ import ( "github.com/aws/amazon-ecs-agent/agent/tcs/model/ecstcs" "github.com/aws/amazon-ecs-agent/agent/wsclient" mock_wsconn "github.com/aws/amazon-ecs-agent/agent/wsclient/wsconn/mock" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/docker/docker/api/types" @@ -574,6 +576,7 @@ func TestMetricsDisabled(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + ctx, cancel := context.WithCancel(context.TODO()) conn := mock_wsconn.NewMockWebsocketConn(ctrl) mockStatsEngine := mock_stats.NewMockEngine(ctrl) @@ -583,10 +586,12 @@ func TestMetricsDisabled(t *testing.T) { cs.SetConnection(conn) published := make(chan struct{}) - readed := make(chan struct{}) + read := make(chan struct{}) // stats engine should only be called for getting health metrics - mockStatsEngine.EXPECT().GetPublishMetricsTicker().Return(time.NewTicker(config.DefaultContainerMetricsPublishInterval)).MinTimes(1) + mockStatsEngine.EXPECT().GetPublishMetricsTicker().Do(func() { + cancel() + }).Return(time.NewTicker(config.DefaultContainerMetricsPublishInterval)).Times(1) mockStatsEngine.EXPECT().GetTaskHealthMetrics().Return(&ecstcs.HealthMetadata{ Cluster: aws.String("TestMetricsDisabled"), ContainerInstance: aws.String("container_instance"), @@ -595,7 +600,7 @@ func TestMetricsDisabled(t *testing.T) { }, []*ecstcs.TaskHealth{{}}, nil).MinTimes(1) conn.EXPECT().SetReadDeadline(gomock.Any()).Return(nil).MinTimes(1) conn.EXPECT().ReadMessage().Do(func() { - readed <- struct{}{} + read <- struct{}{} }).Return(1, nil, nil).MinTimes(1) conn.EXPECT().SetWriteDeadline(gomock.Any()).Return(nil).MinTimes(1) conn.EXPECT().WriteMessage(gomock.Any(), gomock.Any()).Do(func(messageType int, data []byte) { @@ -607,7 +612,13 @@ func TestMetricsDisabled(t *testing.T) { assert.NoError(t, err) }() <-published - <-readed + <-read + + // Wait for the context to be cancelled. This ensures that the publishMetrics() go routine started by cs.Serve() + // always runs and GetPublishMetricsTicker mock call is triggered. + select { + case <-ctx.Done(): + } } func TestCreatePublishHealthRequestsEmpty(t *testing.T) { From cea7a560d7179ab67af181e82c40e13fcb2041a6 Mon Sep 17 00:00:00 2001 From: Anuj Singh Date: Wed, 22 Feb 2023 01:27:30 -0800 Subject: [PATCH 3/3] make TestGetHostPortRange unit test deterministic --- agent/utils/ephemeral_ports.go | 69 +++++++++++++++++------------ agent/utils/ephemeral_ports_test.go | 26 ++++++++++- 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/agent/utils/ephemeral_ports.go b/agent/utils/ephemeral_ports.go index 25caaedb6a..aff87cdf47 100644 --- a/agent/utils/ephemeral_ports.go +++ b/agent/utils/ephemeral_ports.go @@ -22,6 +22,7 @@ import ( "time" "github.com/docker/go-connections/nat" + "github.com/pkg/errors" ) // From https://www.kernel.org/doc/html/latest//networking/ip-sysctl.html#ip-variables @@ -33,7 +34,8 @@ const ( var ( // Injection point for UTs - randIntFunc = rand.Intn + randIntFunc = rand.Intn + isPortAvailableFunc = isPortAvailable // portLock is a mutex lock used to prevent two concurrent tasks to get the same host ports. portLock sync.Mutex ) @@ -132,34 +134,12 @@ func GetHostPortRange(numberOfPorts int, protocol string, dynamicHostPortRange s func getHostPortRange(numberOfPorts, start, end int, protocol string) (string, int, error) { var resultStartPort, resultEndPort, n int for port := start; port <= end; port++ { - portStr := strconv.Itoa(port) - // check if port is available - if protocol == "tcp" { - // net.Listen announces on the local tcp network - ln, err := net.Listen(protocol, ":"+portStr) - // either port is unavailable or some error occurred while listening, we proceed to the next port - if err != nil { - continue - } - // let's close the listener first - err = ln.Close() - if err != nil { - continue - } - } else if protocol == "udp" { - // net.ListenPacket announces on the local udp network - ln, err := net.ListenPacket(protocol, ":"+portStr) - // either port is unavailable or some error occurred while listening, we proceed to the next port - if err != nil { - continue - } - // let's close the listener first - err = ln.Close() - if err != nil { - continue - } + isAvailable, err := isPortAvailableFunc(port, protocol) + if !isAvailable || err != nil { + // either port is unavailable or some error occurred while listening or closing the listener, + // we proceed to the next port + continue } - // check if current port is contiguous relative to lastPort if port-resultEndPort != 1 { resultStartPort = port @@ -182,3 +162,36 @@ func getHostPortRange(numberOfPorts, start, end int, protocol string) (string, i return fmt.Sprintf("%d-%d", resultStartPort, resultEndPort), resultEndPort, nil } + +// isPortAvailable checks if a port is available +func isPortAvailable(port int, protocol string) (bool, error) { + portStr := strconv.Itoa(port) + switch protocol { + case "tcp": + // net.Listen announces on the local tcp network + ln, err := net.Listen(protocol, ":"+portStr) + if err != nil { + return false, err + } + // let's close the listener first + err = ln.Close() + if err != nil { + return false, err + } + return true, nil + case "udp": + // net.ListenPacket announces on the local udp network + ln, err := net.ListenPacket(protocol, ":"+portStr) + if err != nil { + return false, err + } + // let's close the listener first + err = ln.Close() + if err != nil { + return false, err + } + return true, nil + default: + return false, errors.New("invalid protocol") + } +} diff --git a/agent/utils/ephemeral_ports_test.go b/agent/utils/ephemeral_ports_test.go index a8ef7c9b88..54e9c21e89 100644 --- a/agent/utils/ephemeral_ports_test.go +++ b/agent/utils/ephemeral_ports_test.go @@ -79,6 +79,7 @@ func TestGetHostPortRange(t *testing.T) { testDynamicHostPortRange string protocol string expectedLastAssignedPort []int + isPortAvailableFunc func(port int, protocol string) (bool, error) numberOfRequests int expectedError error }{ @@ -88,6 +89,7 @@ func TestGetHostPortRange(t *testing.T) { testDynamicHostPortRange: "40001-40080", protocol: testTCPProtocol, expectedLastAssignedPort: []int{40010}, + isPortAvailableFunc: func(port int, protocol string) (bool, error) { return true, nil }, numberOfRequests: 1, expectedError: nil, }, @@ -97,6 +99,7 @@ func TestGetHostPortRange(t *testing.T) { testDynamicHostPortRange: "40001-40080", protocol: testUDPProtocol, expectedLastAssignedPort: []int{40040}, + isPortAvailableFunc: func(port int, protocol string) (bool, error) { return true, nil }, numberOfRequests: 1, expectedError: nil, }, @@ -106,6 +109,7 @@ func TestGetHostPortRange(t *testing.T) { testDynamicHostPortRange: "40001-40080", protocol: testTCPProtocol, expectedLastAssignedPort: []int{40060, 40000}, + isPortAvailableFunc: func(port int, protocol string) (bool, error) { return true, nil }, numberOfRequests: 2, expectedError: nil, }, @@ -115,24 +119,42 @@ func TestGetHostPortRange(t *testing.T) { testDynamicHostPortRange: "40001-40080", protocol: testUDPProtocol, expectedLastAssignedPort: []int{40015}, + isPortAvailableFunc: func(port int, protocol string) (bool, error) { return true, nil }, numberOfRequests: 1, expectedError: nil, }, { - testName: "contiguous hostPortRange not found", + testName: "contiguous hostPortRange not found, numberOfPorts more than available", numberOfPorts: 20, testDynamicHostPortRange: "40001-40005", protocol: testTCPProtocol, + isPortAvailableFunc: func(port int, protocol string) (bool, error) { return true, nil }, numberOfRequests: 1, expectedError: errors.New("20 contiguous host ports unavailable"), }, + { + testName: "contiguous hostPortRange not found, no ports available on the host", + numberOfPorts: 5, + testDynamicHostPortRange: "40001-40005", + protocol: testTCPProtocol, + isPortAvailableFunc: func(port int, protocol string) (bool, error) { return false, nil }, + numberOfRequests: 1, + expectedError: errors.New("5 contiguous host ports unavailable"), + }, } + // mock isPortAvailable() for unit test + // this ensures that the test doesn't rely on the runtime port availability on the host + isPortAvailableFuncTmp := isPortAvailableFunc + defer func() { + isPortAvailableFunc = isPortAvailableFuncTmp + }() + for _, tc := range testCases { t.Run(tc.testName, func(t *testing.T) { for i := 0; i < tc.numberOfRequests; i++ { + isPortAvailableFunc = tc.isPortAvailableFunc if tc.expectedError == nil { - hostPortRange, err := GetHostPortRange(tc.numberOfPorts, tc.protocol, tc.testDynamicHostPortRange) assert.NoError(t, err)