// TODO(sgotti) I'm not sure setting default os and arch also for image // dependencies is correct since it may break noarch dependencies. Reference: // https://github.com/coreos/rkt/pull/2317 func (db *distBundle) setAppDefaults() error { app := db.dist.(*dist.Appc).App() if _, ok := app.Labels["arch"]; !ok { app.Labels["arch"] = runtime.GOARCH } if _, ok := app.Labels["os"]; !ok { app.Labels["os"] = runtime.GOOS } if err := types.IsValidOSArch(app.Labels, stage0.ValidOSArch); err != nil { return errwrap.Wrap(fmt.Errorf("invalid Appc distribution %q", db.image), err) } db.dist = dist.NewAppcFromApp(app) return nil }
func (f *Fetcher) addImageDeps(hash string, imgsl *list.List, seen map[string]dist.Distribution) error { dependencies, err := f.getImageDeps(hash) if err != nil { return errwrap.Wrap(fmt.Errorf("failed to get dependencies for image ID %q", hash), err) } for _, d := range dependencies { imgName := d.ImageName.String() app, err := discovery.NewApp(imgName, d.Labels.ToMap()) if err != nil { return errwrap.Wrap(fmt.Errorf("one of image ID's %q dependencies (image %q) is invalid", hash, imgName), err) } d := dist.NewAppcFromApp(app) // To really catch already seen deps the saved string must be a // reproducible string keeping the labels order for _, sd := range seen { if d.Equals(sd) { continue } } imgsl.PushBack(d) seen[d.CIMD().String()] = d } return nil }
// DistFromImageString return the distribution for the given input image string func DistFromImageString(is string) (dist.Distribution, error) { u, err := url.Parse(is) if err != nil { return nil, errwrap.Wrap(fmt.Errorf("failed to parse image url %q", is), err) } // Convert user friendly image string names to internal distribution URIs // file:///full/path/to/aci/file.aci -> archive:aci:file%3A%2F%2F%2Ffull%2Fpath%2Fto%2Faci%2Ffile.aci switch u.Scheme { case "": // no scheme given, hence it is an appc image name or path appImageType := guessAppcOrPath(is, []string{schema.ACIExtension}) switch appImageType { case imageStringName: app, err := discovery.NewAppFromString(is) if err != nil { return nil, fmt.Errorf("invalid appc image string %q: %v", is, err) } return dist.NewAppcFromApp(app), nil case imageStringPath: absPath, err := filepath.Abs(is) if err != nil { return nil, errwrap.Wrap(fmt.Errorf("failed to get an absolute path for %q", is), err) } is = "file://" + absPath // given a file:// image string, call this function again to return an ACI distribution return DistFromImageString(is) default: return nil, fmt.Errorf("invalid image string type %q", appImageType) } case "file", "http", "https": // An ACI archive with any transport type (file, http, s3 etc...) and final aci extension if filepath.Ext(u.Path) == schema.ACIExtension { dist, err := dist.NewACIArchiveFromTransportURL(u) if err != nil { return nil, fmt.Errorf("archive distribution creation error: %v", err) } return dist, nil } case "docker": // Accept both docker: and docker:// uri dockerStr := is if strings.HasPrefix(dockerStr, "docker://") { dockerStr = strings.TrimPrefix(dockerStr, "docker://") } else if strings.HasPrefix(dockerStr, "docker:") { dockerStr = strings.TrimPrefix(dockerStr, "docker:") } dist, err := dist.NewDockerFromString(dockerStr) if err != nil { return nil, fmt.Errorf("docker distribution creation error: %v", err) } return dist, nil case dist.Scheme: // cimd return dist.Parse(is) default: // any other scheme is a an appc image name, i.e. "my-app:v1.0" app, err := discovery.NewAppFromString(is) if err != nil { return nil, fmt.Errorf("invalid appc image string %q: %v", is, err) } return dist.NewAppcFromApp(app), nil } return nil, fmt.Errorf("invalid image string %q", is) }