From 76d80295faffc60963ed45aa99d4b025593df1cc Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Sat, 9 Jul 2022 23:30:14 +0200 Subject: [PATCH] container: add new resolver helper Add a new class `container.Resolver` which can be used to resolve multiple container images to their respective ids in parallel. It should make it easy for all existing tools and api endpoints to adpot container resultion. --- internal/container/resolver.go | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 internal/container/resolver.go diff --git a/internal/container/resolver.go b/internal/container/resolver.go new file mode 100644 index 000000000..6e5a41506 --- /dev/null +++ b/internal/container/resolver.go @@ -0,0 +1,73 @@ +package container + +import ( + "context" + "fmt" + "strings" +) + +type resolveResult struct { + spec Spec + err error +} + +type Resolver struct { + jobs int + queue chan resolveResult + + ctx context.Context + + Arch string +} + +func NewResolver(arch string) Resolver { + return Resolver{ + ctx: context.Background(), + queue: make(chan resolveResult, 2), + Arch: arch, + } +} + +func (r *Resolver) Add(source, name string, TLSVerify *bool) { + client, err := NewClient(source) + r.jobs += 1 + + if err != nil { + r.queue <- resolveResult{err: err} + return + } + + client.SetTLSVerify(TLSVerify) + client.SetArchitectureChoice(r.Arch) + + go func() { + spec, err := client.Resolve(r.ctx, name) + if err != nil { + err = fmt.Errorf("'%s': %w", source, err) + } + r.queue <- resolveResult{spec: spec, err: err} + }() +} + +func (r *Resolver) Finish() ([]Spec, error) { + + specs := make([]Spec, 0, r.jobs) + errs := make([]string, 0, r.jobs) + for r.jobs > 0 { + result := <-r.queue + r.jobs -= 1 + + if result.err == nil { + specs = append(specs, result.spec) + } else { + errs = append(errs, result.err.Error()) + } + } + + if len(errs) > 0 { + detail := strings.Join(errs, "; ") + return specs, fmt.Errorf("failed to resolve container: %s", detail) + } + + return specs, nil +}