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

feat: show stopped tasks when no running tasks #286

Merged
merged 3 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
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
63 changes: 46 additions & 17 deletions internal/api/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/aws/aws-sdk-go-v2/service/ecs"
"github.com/aws/aws-sdk-go-v2/service/ecs/types"
"github.com/keidarcy/e1s/internal/utils"
)

// Equivalent to
Expand All @@ -16,40 +17,68 @@ import (
// aws ecs describe-tasks --cluster ${cluster} --tasks ${taskID}
// OR
// aws ecs list-tasks --cluster ${cluster} --desired-status STOPPED
func (store *Store) ListTasks(clusterName, serviceName *string, status types.DesiredStatus) ([]types.Task, error) {
// `aws ecs list-tasks --cluster ${CLUSTER} --service-name ${SERVICE} --desired-status STOPPED` return nothing
// `aws ecs list-tasks --cluster ${CLUSTER} --desired-status STOPPED` return all stopped tasks in cluster
func (store *Store) ListTasks(clusterName, serviceName *string, status types.DesiredStatus) ([]types.Task, bool, error) {
limit := int32(100)
listTasksOutput, err := store.ecs.ListTasks(context.Background(), &ecs.ListTasksInput{
resultTasks := []types.Task{}
describeTasksInclude := []types.TaskField{
types.TaskFieldTags,
}
listTaskServiceName := serviceName
noRunningShowStopped := false

// true when show desiredStatus:stopped tasks
if status == types.DesiredStatusStopped {
listTaskServiceName = nil
noRunningShowStopped = true
}

listTasksOutput, _ := store.ecs.ListTasks(context.Background(), &ecs.ListTasksInput{
Cluster: clusterName,
ServiceName: serviceName,
ServiceName: listTaskServiceName,
DesiredStatus: status,
MaxResults: &limit,
})
if err != nil {
slog.Warn("failed to run aws api to list tasks", "error", err)
return []types.Task{}, err
}
if len(listTasksOutput.TaskArns) == 0 {
return nil, nil
}

include := []types.TaskField{
types.TaskFieldTags,
if status == types.DesiredStatusStopped && len(listTasksOutput.TaskArns) == 0 {
return nil, noRunningShowStopped, nil
}

resultTasks := []types.Task{}
if status == types.DesiredStatusRunning && len(listTasksOutput.TaskArns) == 0 {
listTasksOutput, _ := store.ecs.ListTasks(context.Background(), &ecs.ListTasksInput{
Cluster: clusterName,
DesiredStatus: types.DesiredStatusStopped,
MaxResults: &limit,
})
if len(listTasksOutput.TaskArns) == 0 {
return nil, noRunningShowStopped, nil
}
noRunningShowStopped = true
}

describeTasksOutput, err := store.ecs.DescribeTasks(context.Background(), &ecs.DescribeTasksInput{
Cluster: clusterName,
Tasks: listTasksOutput.TaskArns,
Include: include,
Include: describeTasksInclude,
})

if err != nil {
slog.Warn("failed to run aws api to describe tasks", "error", err)
return []types.Task{}, err
return []types.Task{}, noRunningShowStopped, err
}

resultTasks = append(resultTasks, describeTasksOutput.Tasks...)
if len(describeTasksOutput.Tasks) > 0 {
if !noRunningShowStopped {
resultTasks = append(resultTasks, describeTasksOutput.Tasks...)
} else {
for _, t := range describeTasksOutput.Tasks {
if *serviceName == utils.GetServiceByTaskGroup(t.Group) {
resultTasks = append(resultTasks, t)
}
}
}
}

// sort tasks by task name
sort.Slice(resultTasks, func(i, j int) bool {
Expand All @@ -63,7 +92,7 @@ func (store *Store) ListTasks(clusterName, serviceName *string, status types.Des
})
}

return resultTasks, nil
return resultTasks, noRunningShowStopped, nil
}

// aws ecs register-task-definition --family ${{family}} --...
Expand Down
2 changes: 1 addition & 1 deletion internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func ImageInfo(imageURL *string) (string, string) {
}

// Get service name by describe task group name
func ShowServiceByGroup(group *string) string {
func GetServiceByTaskGroup(group *string) string {
if group == nil {
return EmptyText
}
Expand Down
6 changes: 5 additions & 1 deletion internal/view/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package view

import (
"errors"
"log/slog"
"strings"
"time"
Expand All @@ -16,6 +17,7 @@ import (
)

var theme color.Colors
var ErrNoNeedReload = errors.New("no need reload")

// Entity contains ECS resources to show, use uppercase to make items like app.cluster easy to access
type Entity struct {
Expand Down Expand Up @@ -288,7 +290,9 @@ func (app *App) showPrimaryKindPage(k kind, reload bool) error {
return err
}
if !reload {
app.Notice.Infof("Viewing %s...", app.kind.String())
if app.taskStatus != types.DesiredStatusStopped {
app.Notice.Infof("Viewing %s...", app.kind.String())
}
} else {
slog.Debug("Reload in showPrimaryKindPage")
}
Expand Down
4 changes: 2 additions & 2 deletions internal/view/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ func (v *clusterView) tableParam() (title string, headers []string, dataBuilder
"Status",
"Services",
"Tasks ▾",
"Container instances",
"Capacity providers",
"Registered container instances",
}
dataBuilder = func() (data [][]string) {
for _, c := range v.clusters {
Expand All @@ -171,8 +171,8 @@ func (v *clusterView) tableParam() (title string, headers []string, dataBuilder
row = append(row, utils.ShowGreenGrey(c.Status, "active"))
row = append(row, utils.ShowInt(&c.ActiveServicesCount))
row = append(row, tasks)
row = append(row, utils.ShowInt(&c.RegisteredContainerInstancesCount)+" EC2")
row = append(row, utils.ShowArray(c.CapacityProviders))
row = append(row, utils.ShowInt(&c.RegisteredContainerInstancesCount))

data = append(data, row)
}
Expand Down
22 changes: 13 additions & 9 deletions internal/view/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,28 @@ func (app *App) showTasksPages(reload bool) error {
serviceName = nil
}

// true when show desiredStatus:stopped tasks
if app.taskStatus == types.DesiredStatusStopped {
serviceName = nil
}

tasks, err := app.Store.ListTasks(app.cluster.ClusterName, serviceName, app.taskStatus)
tasks, noRunningShowStopped, err := app.Store.ListTasks(app.cluster.ClusterName, serviceName, app.taskStatus)

if err != nil {
slog.Warn("failed to show tasks pages", "error", err)
app.back()
return err
}

if noRunningShowStopped && len(tasks) > 0 {
app.Notice.Warn("0 running task show stopped")
}

// no tasks exists do nothing
if len(tasks) == 0 {
err := fmt.Errorf("no valid %s task", strings.ToLower(string(app.taskStatus)))
app.back()
return err
if app.taskStatus == types.DesiredStatusRunning {
app.back()
return err
} else {
app.Notice.Info("0 stopped task show running")
return nil
}
}

view := newTaskView(tasks, app)
Expand Down Expand Up @@ -208,7 +212,7 @@ func (v *taskView) tableParam() (title string, headers []string, dataBuilder fun
row = append(row, utils.ArnToName(t.TaskArn))
row = append(row, utils.ShowGreenGrey(t.LastStatus, "running"))
row = append(row, utils.ShowGreenGrey(&health, "healthy"))
row = append(row, utils.ShowServiceByGroup(t.Group))
row = append(row, utils.GetServiceByTaskGroup(t.Group))
row = append(row, utils.ArnToName(t.TaskDefinitionArn))
row = append(row, strconv.Itoa(len(t.Containers)))
row = append(row, utils.ShowString(t.Cpu))
Expand Down