From 70980590622d673a2fdfb6f3bf6b4d50eabf1c37 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Wed, 20 May 2015 20:38:11 +0200 Subject: [PATCH] rkt: fallback to local store fetch if discovery fails. If discovery fails for any reason (no domain, not meta tags but also network errors) fallback to local store app fetch. The fallback isn't done if discovery returns valid endpoints but the the image fetching from the returned endpoints fails for any reason (network errors, wrong signature, etc...). --- rkt/images.go | 76 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/rkt/images.go b/rkt/images.go index a529a71..630ba1d 100644 --- a/rkt/images.go +++ b/rkt/images.go @@ -217,41 +217,28 @@ func (f *fetcher) fetchSingleImage(img string, asc string, discover bool) (strin } if discover && u.Scheme == "" { - if f.local { - app, err := discovery.NewAppFromString(img) - if err != nil { - return "", err - } - labels, err := types.LabelsFromMap(app.Labels) - if err != nil { - return "", err - } - return f.s.GetACI(app.Name, labels) - } if app := newDiscoveryApp(img); app != nil { - stdout("rkt: searching for app image %s", img) - ep, attempts, err := discovery.DiscoverEndpoints(*app, true) - - if globalFlags.Debug { - for _, a := range attempts { - stderr("meta tag 'ac-discovery' not found on %s: %v", a.Prefix, a.Error) + var discoveryError error + if !f.local { + stdout("rkt: searching for app image %s", img) + ep, err := discoverApp(app, true) + if err != nil { + discoveryError = err + } else { + latest := false + // No specified version label, mark it as latest + if _, ok := app.Labels["version"]; !ok { + latest = true + } + return f.fetchImageFromEndpoints(ep, ascFile, latest) } } - - if err != nil { - return "", err + if discoveryError != nil { + stdout("discovery failed for %q: %v. Trying to find image in the store.", img, discoveryError) } - - if len(ep.ACIEndpoints) == 0 { - return "", fmt.Errorf("no endpoints discovered") + if f.local || discoveryError != nil { + return f.fetchImageFromStore(img) } - - latest := false - // No specified version label, mark it as latest - if _, ok := app.Labels["version"]; !ok { - latest = true - } - return f.fetchImageFromEndpoints(ep, ascFile, latest) } } @@ -263,6 +250,19 @@ func (f *fetcher) fetchSingleImage(img string, asc string, discover bool) (strin return f.fetchImageFromURL(u.String(), u.Scheme, ascFile, false) } +func (f *fetcher) fetchImageFromStore(img string) (string, error) { + // TODO(sgotti) redo newDiscoveryApp as discovery.DiscoverEndpoint may + // have added a defaultVersion label (nil is ignored as it's already + // checked in the calling function) + // remove when fixed in appc/spec#412 + app := newDiscoveryApp(img) + labels, err := types.LabelsFromMap(app.Labels) + if err != nil { + return "", err + } + return f.s.GetACI(app.Name, labels) +} + func (f *fetcher) fetchImageFromEndpoints(ep *discovery.Endpoints, ascFile *os.File, latest bool) (string, error) { return f.fetchImageFrom(ep.ACIEndpoints[0].ACI, ep.ACIEndpoints[0].ASC, "", ascFile, latest) } @@ -572,3 +572,19 @@ func newDiscoveryApp(img string) *discovery.App { } return app } + +func discoverApp(app *discovery.App, insecure bool) (*discovery.Endpoints, error) { + ep, attempts, err := discovery.DiscoverEndpoints(*app, insecure) + if globalFlags.Debug { + for _, a := range attempts { + stderr("meta tag 'ac-discovery' not found on %s: %v", a.Prefix, a.Error) + } + } + if err != nil { + return nil, err + } + if len(ep.ACIEndpoints) == 0 { + return nil, fmt.Errorf("no endpoints discovered") + } + return ep, nil +}