service/progress: ServiceProgress: avoid fuzzy matching service ID in loop

Tasks with a service filter will result in the daemon performing a lookup
of the full service ID, then updating the provided filter with the actual
ID: 96ded2a1ba/daemon/cluster/tasks.go (L15-L30)

The `getService()` helper has a fast-path for situations where the given
filter is a full ID, before falling back to fuzzy-logic to search filters
by service name or prefix, which would return an error if the result is
ambiguous;
96ded2a1ba/daemon/cluster/helpers.go (L62-L81)

The loop executed here calls `client.ServiceInspectWithRaw()` to get info
of the service, and that method is ultimately calling the exact same
`getService()` helper on the daemon side, which means that we don't need
to repeat the work; we can use the `Service.ID` resolved from that call,
and use it to apply as filter for listing the tasks.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2025-02-03 15:42:23 +01:00
parent e88b1939f7
commit a4288003bd
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C

View File

@ -79,14 +79,6 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
signal.Notify(sigint, os.Interrupt)
defer signal.Stop(sigint)
taskFilter := filters.NewArgs()
taskFilter.Add("service", serviceID)
taskFilter.Add("_up-to-date", "true")
getUpToDateTasks := func() ([]swarm.Task, error) {
return apiClient.TaskList(ctx, types.TaskListOptions{Filters: taskFilter})
}
var (
updater progressUpdater
converged bool
@ -151,7 +143,10 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
return nil
}
tasks, err := getUpToDateTasks()
tasks, err := apiClient.TaskList(ctx, types.TaskListOptions{Filters: filters.NewArgs(
filters.KeyValuePair{Key: "service", Value: service.ID},
filters.KeyValuePair{Key: "_up-to-date", Value: "true"},
)})
if err != nil {
return err
}
@ -218,7 +213,10 @@ func ServiceProgress(ctx context.Context, apiClient client.APIClient, serviceID
}
}
func getActiveNodes(ctx context.Context, apiClient client.APIClient) (map[string]struct{}, error) {
// getActiveNodes returns all nodes that are currently not in status [swarm.NodeStateDown].
//
// TODO(thaJeztah): this should really be a filter on [apiClient.NodeList] instead of being filtered on the client side.
func getActiveNodes(ctx context.Context, apiClient client.NodeAPIClient) (map[string]struct{}, error) {
nodes, err := apiClient.NodeList(ctx, types.NodeListOptions{})
if err != nil {
return nil, err