func runDiscover(args []string) (exit int) { if len(args) < 1 { stderr("discover: at least one name required") } for _, name := range args { app, err := discovery.NewAppFromString(name) if app.Labels["os"] == "" { app.Labels["os"] = runtime.GOOS } if app.Labels["arch"] == "" { app.Labels["arch"] = runtime.GOARCH } if err != nil { stderr("%s: %s", name, err) return 1 } eps, attempts, err := discovery.DiscoverEndpoints(*app, transportFlags.Insecure) if err != nil { stderr("error fetching %s: %s", name, err) return 1 } for _, a := range attempts { fmt.Printf("discover walk: prefix: %s error: %v\n", a.Prefix, a.Error) } for _, aciEndpoint := range eps.ACIEndpoints { fmt.Printf("ACI: %s, ASC: %s\n", aciEndpoint.ACI, aciEndpoint.ASC) } if len(eps.Keys) > 0 { fmt.Println("Keys: " + strings.Join(eps.Keys, ",")) } } return }
func (n ACFullname) LatestVersion() (string, error) { app, err := discovery.NewAppFromString(n.Name() + ":latest") if app.Labels["os"] == "" { app.Labels["os"] = "linux" } if app.Labels["arch"] == "" { app.Labels["arch"] = "amd64" } endpoint, _, err := discovery.DiscoverEndpoints(*app, nil, false) if err != nil { return "", errors.Annotate(err, "Latest discovery fail") } r, _ := regexp.Compile(`^(\d+\.)?(\d+\.)?(\*|\d+)(\-[\dA-Za-z]+){0,1}$`) // TODO this is nexus specific if len(endpoint.ACIEndpoints) == 0 { return "", errs.WithF(data.WithField("aci", string(n)), "Discovery does not give an endpoint to check latest version") } url := getRedirectForLatest(endpoint.ACIEndpoints[0].ACI) logs.WithField("url", url).Debug("latest verion url") for _, part := range strings.Split(url, "/") { if r.Match([]byte(part)) { return part, nil } } return "", errors.New("No latest version found") }
func (n ACFullname) LatestVersion() (string, error) { app, err := discovery.NewAppFromString(n.Name() + ":latest") if app.Labels["os"] == "" { app.Labels["os"] = "linux" } if app.Labels["arch"] == "" { app.Labels["arch"] = "amd64" } endpoint, _, err := discovery.DiscoverEndpoints(*app, false) if err != nil { return "", errors.Annotate(err, "Latest discovery fail") } r, _ := regexp.Compile(`^(\d+\.)?(\d+\.)?(\*|\d+)$`) url := getRedirectForLatest(endpoint.ACIEndpoints[0].ACI) log.Debug("latest version url is ", url) for _, part := range strings.Split(url, "/") { if r.Match([]byte(part)) { return part, nil } } return "", errors.New("No latest version found") }
// RetrieveImage can be used to retrieve a remote image, and optionally discover // an image based on the App Container Image Discovery specification. Supports // handling local images as well as func RetrieveImage(imageUri string, insecure bool) (ReaderCloserSeeker, error) { u, err := url.Parse(imageUri) if err != nil { return nil, err } switch u.Scheme { case "file": // for file:// urls, just load the file and return it return os.Open(u.Path) case "http", "https": // Handle HTTP retrievals, wrapped with a tempfile that cleans up. resp, err := Client.Get(imageUri) if err != nil { return nil, err } defer resp.Body.Close() switch resp.StatusCode { case http.StatusOK: default: return nil, fmt.Errorf("HTTP %d on retrieving %q", resp.StatusCode, imageUri) } return newTempReader(resp.Body) case "": app, err := discovery.NewAppFromString(imageUri) if err != nil { return nil, err } endpoints, _, err := discovery.DiscoverEndpoints(*app, insecure) if err != nil { return nil, err } for _, ep := range endpoints.ACIEndpoints { r, err := RetrieveImage(ep.ACI, insecure) if err != nil { continue } // FIXME should also attempt to validate the signature return r, nil } return nil, fmt.Errorf("failed to find a valid image for %q", imageUri) default: return nil, fmt.Errorf("%q scheme not supported", u.Scheme) } }
func runDiscover(args []string) (exit int) { if len(args) < 1 { stderr("discover: at least one name required") } for _, name := range args { app, err := discovery.NewAppFromString(name) if app.Labels["os"] == "" { app.Labels["os"] = runtime.GOOS } if app.Labels["arch"] == "" { app.Labels["arch"] = runtime.GOARCH } if err != nil { stderr("%s: %s", name, err) return 1 } insecure := discovery.InsecureNone if transportFlags.Insecure { insecure = discovery.InsecureTls | discovery.InsecureHttp } eps, attempts, err := discovery.DiscoverEndpoints(*app, nil, insecure) if err != nil { stderr("error fetching %s: %s", name, err) return 1 } for _, a := range attempts { fmt.Printf("discover walk: prefix: %s error: %v\n", a.Prefix, a.Error) } if outputJson { jsonBytes, err := json.MarshalIndent(&eps, "", " ") if err != nil { stderr("error generating JSON: %s", err) return 1 } fmt.Println(string(jsonBytes)) } else { for _, aciEndpoint := range eps.ACIEndpoints { fmt.Printf("ACI: %s, ASC: %s\n", aciEndpoint.ACI, aciEndpoint.ASC) } if len(eps.Keys) > 0 { fmt.Println("Keys: " + strings.Join(eps.Keys, ",")) } } } return }
func (s Service) discoverPod(name cntspec.ACFullname) []cntspec.ACFullname { logAci := s.log.WithField("pod", name) app, err := discovery.NewAppFromString(name.String()) if app.Labels["os"] == "" { app.Labels["os"] = "linux" } if app.Labels["arch"] == "" { app.Labels["arch"] = "amd64" } endpoint, _, err := discovery.DiscoverEndpoints(*app, false) if err != nil { logAci.WithError(err).Fatal("pod discovery failed") } url := endpoint.ACIEndpoints[0].ACI url = strings.Replace(url, "=aci", "=pod", 1) // TODO this is nexus specific logUrl := logAci.WithField("url", url) response, err := http.Get(url) if err != nil { logUrl.WithError(err).Fatal("Cannot get pod manifest content") return nil } else { if response.StatusCode != 200 { logUrl.WithField("status_code", response.StatusCode).WithField("status_message", response.Status). Fatal("Receive response error for discovery") } defer response.Body.Close() content, err := ioutil.ReadAll(response.Body) if err != nil { logUrl.WithError(err).Fatal("Cannot read pod manifest content") } tmpMap := make(map[string][]cntspec.ACFullname, 1) if err := s.podManifestToMap(tmpMap, content); err != nil { logUrl.WithError(err).Fatal("Cannot read pod content") } acis := tmpMap[name.Name()] if acis == nil { logUrl.Fatal("Discovered pod name does not match requested") } return acis } }
func discoverACI(app discovery.App, asc *os.File) (*os.File, *os.File, error) { var aci *os.File // TODO: hostHeaders, insecure if eps, _, err := discovery.DiscoverEndpoints(app, nil, 0); err != nil { return nil, nil, err } else { var err error if asc == nil { err = nil for _, ep := range eps.ACIEndpoints { if af, er1 := OpenLocation(ep.ASC); er1 != nil { err = multierror.Append(err, er1) } else { asc = af break } } if err != nil { return nil, nil, err } } err = nil for _, ep := range eps.ACIEndpoints { if af, er1 := OpenLocation(ep.ACI); er1 != nil { err = multierror.Append(err, er1) } else { aci = af break } if aci == nil { if asc != nil { asc.Close() } return nil, nil, err } } return aci, asc, nil } }
func (cnt *Img) processFrom() { if cnt.manifest.From != "" { log.Get().Info("Prepare rootfs from " + cnt.manifest.From) app, err := discovery.NewAppFromString(string(cnt.manifest.From)) if app.Labels["os"] == "" { app.Labels["os"] = "linux" } if app.Labels["arch"] == "" { app.Labels["arch"] = "amd64" } endpoint, _, err := discovery.DiscoverEndpoints(*app, false) if err != nil { panic(err) } url := endpoint.ACIEndpoints[0].ACI aciPath := config.GetConfig().AciPath + "/" + string(cnt.manifest.From) if _, err := os.Stat(aciPath + "/image.aci"); cnt.args.ForceUpdate || os.IsNotExist(err) { if err := os.MkdirAll(aciPath, 0755); err != nil { log.Get().Panic(err) } if err = utils.ExecCmd("wget", "-O", aciPath+"/image.aci", url); err != nil { os.Remove(aciPath + "/image.aci") log.Get().Panic("Cannot download from image", err) } } else { log.Get().Info("Image " + cnt.manifest.From + " Already exists locally, will not be downloaded") } utils.ExecCmd("tar", "xpf", aciPath+"/image.aci", "-C", cnt.target) // utils.ExecCmd("rkt", "--insecure-skip-verify=true", "fetch", cnt.manifest.From) // utils.ExecCmd("rkt", "image", "export", "--overwrite", cnt.manifest.From, cnt.target + "/from.aci") // utils.ExecCmd("tar", "xf", cnt.target + "/from.aci", "-C", cnt.target) // os.Remove(cnt.target + "/from.aci") } }
func (f *nameFetcher) discoverApp(app *discovery.App) (*discovery.Endpoints, error) { insecure := discovery.InsecureNone if f.InsecureFlags.SkipTLSCheck() { insecure = insecure | discovery.InsecureTls } if f.InsecureFlags.AllowHTTP() { insecure = insecure | discovery.InsecureHttp } hostHeaders := config.ResolveAuthPerHost(f.Headers) ep, attempts, err := discovery.DiscoverEndpoints(*app, hostHeaders, insecure) if f.Debug { for _, a := range attempts { log.PrintE(fmt.Sprintf("meta tag 'ac-discovery' not found on %s", 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 }