Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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")
}
Ejemplo n.º 3
0
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")
}
Ejemplo n.º 4
0
// 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)
	}
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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
	}
}
Ejemplo n.º 7
0
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
	}
}
Ejemplo n.º 8
0
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")
	}
}
Ejemplo n.º 9
0
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
}