Beispiel #1
0
// 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
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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)
}