Create a struct to conveniently hold the source parameters for a container resolve request and use it in the Add() function of the resolver.
83 lines
1.4 KiB
Go
83 lines
1.4 KiB
Go
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
|
|
AuthFilePath string
|
|
}
|
|
|
|
type SourceSpec struct {
|
|
Source string
|
|
Name string
|
|
TLSVerify *bool
|
|
}
|
|
|
|
func NewResolver(arch string) Resolver {
|
|
return Resolver{
|
|
ctx: context.Background(),
|
|
queue: make(chan resolveResult, 2),
|
|
Arch: arch,
|
|
}
|
|
}
|
|
|
|
func (r *Resolver) Add(spec SourceSpec) {
|
|
client, err := NewClient(spec.Source)
|
|
r.jobs += 1
|
|
|
|
if err != nil {
|
|
r.queue <- resolveResult{err: err}
|
|
return
|
|
}
|
|
|
|
client.SetTLSVerify(spec.TLSVerify)
|
|
client.SetArchitectureChoice(r.Arch)
|
|
if r.AuthFilePath != "" {
|
|
client.SetAuthFilePath(r.AuthFilePath)
|
|
}
|
|
|
|
go func() {
|
|
spec, err := client.Resolve(r.ctx, spec.Name)
|
|
if err != nil {
|
|
err = fmt.Errorf("'%s': %w", spec.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
|
|
}
|