Beispiel #1
0
func parseApp(args []string) ([]string, *schema.RuntimeApp, error) {
	if len(args) == 0 {
		return nil, nil, nil
	}

	rtapp := schema.RuntimeApp{}

	// Parse first argument (image name)
	if h, err := types.NewHash(args[0]); err == nil {
		rtapp.Image.ID = *h
		rtapp.Name.Set(h.String()) // won't err
	} else if dapp, err := discovery.NewAppFromString(args[0]); err == nil {
		rtapp.Image.Name = &dapp.Name
		rtapp.Name.Set(path.Base(dapp.Name.String())) // won't err here
		if ll, err := types.LabelsFromMap(dapp.Labels); err != nil {
			return args, nil, err
		} else {
			rtapp.Image.Labels = ll
		}
	} else {
		return args, nil, err
	}

	fl := flag.NewFlagSet(args[0], flag.ExitOnError)
	fl.Var(&rtapp.Name, "name", "App name")
	fl.Var((*AnnotationsFlag)(&rtapp.Annotations), "a", "Add annotation (NAME=VALUE)")
	fl.Var((*MountsFlag)(&rtapp.Mounts), "m", "Mount volume (VOLUME[:MOUNTPOINT])")
	// TODO: app override
	fl.Parse(args[1:])
	return fl.Args(), &rtapp, nil
}
Beispiel #2
0
func (f *Fetcher) getStoreKeyFromApp(app *appBundle) (string, error) {
	labels, err := types.LabelsFromMap(app.App.Labels)
	if err != nil {
		return "", errwrap.Wrap(fmt.Errorf("invalid labels in the name %q", app.Str), err)
	}
	key, err := f.S.GetACI(app.App.Name, labels)
	if err != nil {
		switch err.(type) {
		case store.ACINotFoundError:
			return "", err
		default:
			return "", errwrap.Wrap(fmt.Errorf("cannot find image %q", app.Str), err)
		}
	}
	return key, nil
}
Beispiel #3
0
func getStoreKeyFromApp(s *imagestore.Store, img string) (string, error) {
	app, err := discovery.NewAppFromString(img)
	if err != nil {
		return "", errwrap.Wrap(fmt.Errorf("cannot parse the image name %q", img), err)
	}
	labels, err := types.LabelsFromMap(app.Labels)
	if err != nil {
		return "", errwrap.Wrap(fmt.Errorf("invalid labels in the image %q", img), err)
	}
	key, err := s.GetACI(app.Name, labels)
	if err != nil {
		switch err.(type) {
		case imagestore.ACINotFoundError:
			return "", err
		default:
			return "", errwrap.Wrap(fmt.Errorf("cannot find image %q", img), err)
		}
	}
	return key, nil
}
Beispiel #4
0
func parseImageName(name string) (types.ACIdentifier, types.Labels, error) {
	app, err := discovery.NewAppFromString(name)
	if err != nil {
		return "", nil, errors.Trace(err)
	}

	if app.Labels["os"] == "" {
		app.Labels["os"] = runtime.GOOS
	}
	if app.Labels["arch"] == "" {
		app.Labels["arch"] = runtime.GOARCH
	}

	labels, err := types.LabelsFromMap(app.Labels)
	if err != nil {
		return "", nil, errors.Trace(err)
	}

	return app.Name, labels, nil
}
Beispiel #5
0
func (a *ACBuild) beginFromRemoteImage(start string, insecure bool) error {
	app, err := discovery.NewAppFromString(start)
	if err != nil {
		return err
	}
	labels, err := types.LabelsFromMap(app.Labels)
	if err != nil {
		return err
	}

	tmpDepStoreTarPath, err := ioutil.TempDir("", "acbuild-begin-tar")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tmpDepStoreTarPath)

	tmpDepStoreExpandedPath, err := ioutil.TempDir("", "acbuild-begin-expanded")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tmpDepStoreExpandedPath)

	reg := registry.Registry{
		DepStoreTarPath:      tmpDepStoreTarPath,
		DepStoreExpandedPath: tmpDepStoreExpandedPath,
		Insecure:             insecure,
		Debug:                a.Debug,
	}

	err = reg.Fetch(app.Name, labels, 0, false)
	if err != nil {
		if urlerr, ok := err.(*url.Error); ok {
			if operr, ok := urlerr.Err.(*net.OpError); ok {
				if dnserr, ok := operr.Err.(*net.DNSError); ok {
					if dnserr.Err == "no such host" {
						return fmt.Errorf("unknown host when fetching image, check your connection and local file paths must start with '/' or '.'")
					}
				}
			}
		}
		return err
	}

	files, err := ioutil.ReadDir(tmpDepStoreTarPath)
	if err != nil {
		return err
	}

	if len(files) != 1 {
		var filelist string
		for _, file := range files {
			if filelist == "" {
				filelist = file.Name()
			} else {
				filelist = filelist + ", " + file.Name()
			}
		}
		panic("unexpected number of files in store after download: " + filelist)
	}

	return util.ExtractImage(path.Join(tmpDepStoreTarPath, files[0].Name()), a.CurrentACIPath, nil)
}
Beispiel #6
0
func GenerateManifestV22(name string, dockerURL *types.ParsedDockerURL, config *typesV2.ImageConfig, imageDigest string, lowerLayers []*schema.ImageManifest) (*schema.ImageManifest, error) {
	manifest, err := GenerateEmptyManifest(name)
	if err != nil {
		return nil, err
	}

	labels := manifest.Labels.ToMap()
	annotations := manifest.Annotations

	addLabel := func(key, val string) {
		if key != "" && val != "" {
			labels[*appctypes.MustACIdentifier(key)] = val
		}
	}

	addAnno := func(key, val string) {
		if key != "" && val != "" {
			annotations.Set(*appctypes.MustACIdentifier(key), val)
		}
	}

	addLabel("version", dockerURL.Tag)
	addLabel("os", config.OS)
	addLabel("arch", config.Architecture)

	addAnno("author", config.Author)
	addAnno("created", config.Created)

	addAnno(common.AppcDockerRegistryURL, dockerURL.IndexURL)
	addAnno(common.AppcDockerRepository, dockerURL.ImageName)
	addAnno(common.AppcDockerImageID, imageDigest)
	addAnno("created", config.Created)

	if config.Config != nil {
		innerCfg := config.Config
		exec := getExecCommand(innerCfg.Entrypoint, innerCfg.Cmd)
		user, group := parseDockerUser(innerCfg.User)
		var env appctypes.Environment
		for _, v := range innerCfg.Env {
			parts := strings.SplitN(v, "=", 2)
			env.Set(parts[0], parts[1])
		}
		manifest.App = &appctypes.App{
			Exec:             exec,
			User:             user,
			Group:            group,
			Environment:      env,
			WorkingDirectory: innerCfg.WorkingDir,
		}
		manifest.App.MountPoints, err = convertVolumesToMPs(innerCfg.Volumes)
		if err != nil {
			return nil, err
		}
		manifest.App.Ports, err = convertPorts(innerCfg.ExposedPorts, nil)
		if err != nil {
			return nil, err
		}

		ep, cmd, err := generateEPCmdAnnotation(innerCfg.Entrypoint, innerCfg.Cmd)
		if err != nil {
			return nil, err
		}
		if len(ep) > 0 {
			addAnno(common.AppcDockerEntrypoint, ep)
		}
		if len(cmd) > 0 {
			addAnno(common.AppcDockerCmd, cmd)
		}
	}

	for _, lowerLayer := range lowerLayers {
		manifest.Dependencies = append(manifest.Dependencies, appctypes.Dependency{
			ImageName: lowerLayer.Name,
			Labels:    lowerLayer.Labels,
		})
	}

	manifest.Labels, err = appctypes.LabelsFromMap(labels)
	if err != nil {
		return nil, err
	}
	manifest.Annotations = annotations
	return manifest, nil
}
Beispiel #7
0
// GenerateManifest converts the docker manifest format to an appc
// ImageManifest.
func GenerateManifest(layerData types.DockerImageData, dockerURL *types.ParsedDockerURL) (*schema.ImageManifest, error) {
	dockerConfig := layerData.Config
	genManifest := &schema.ImageManifest{}

	appURL := ""
	appURL = dockerURL.IndexURL + "/"
	appURL += dockerURL.ImageName + "-" + layerData.ID
	appURL, err := appctypes.SanitizeACIdentifier(appURL)
	if err != nil {
		return nil, err
	}
	name := appctypes.MustACIdentifier(appURL)
	genManifest.Name = *name

	acVersion, err := appctypes.NewSemVer(schema.AppContainerVersion.String())
	if err != nil {
		panic("invalid appc spec version")
	}
	genManifest.ACVersion = *acVersion

	genManifest.ACKind = appctypes.ACKind(schema.ImageManifestKind)

	var annotations appctypes.Annotations

	labels := make(map[appctypes.ACIdentifier]string)
	parentLabels := make(map[appctypes.ACIdentifier]string)

	addLabel := func(key, val string) {
		if key != "" && val != "" {
			labels[*appctypes.MustACIdentifier(key)] = val
		}
	}

	addParentLabel := func(key, val string) {
		if key != "" && val != "" {
			parentLabels[*appctypes.MustACIdentifier(key)] = val
		}
	}

	addAnno := func(key, val string) {
		if key != "" && val != "" {
			annotations.Set(*appctypes.MustACIdentifier(key), val)
		}
	}

	addLabel("layer", layerData.ID)
	addLabel("version", dockerURL.Tag)
	addLabel("os", layerData.OS)
	addParentLabel("os", layerData.OS)
	addLabel("arch", layerData.Architecture)
	addParentLabel("arch", layerData.OS)

	addAnno("authors", layerData.Author)
	epoch := time.Unix(0, 0)
	if !layerData.Created.Equal(epoch) {
		addAnno("created", layerData.Created.Format(time.RFC3339))
	}
	addAnno("docker-comment", layerData.Comment)
	addAnno(common.AppcDockerRegistryURL, dockerURL.IndexURL)
	addAnno(common.AppcDockerRepository, dockerURL.ImageName)
	addAnno(common.AppcDockerImageID, layerData.ID)
	addAnno(common.AppcDockerParentImageID, layerData.Parent)

	if dockerConfig != nil {
		exec := getExecCommand(dockerConfig.Entrypoint, dockerConfig.Cmd)
		if exec != nil {
			user, group := parseDockerUser(dockerConfig.User)
			var env appctypes.Environment
			for _, v := range dockerConfig.Env {
				parts := strings.SplitN(v, "=", 2)
				env.Set(parts[0], parts[1])
			}
			app := &appctypes.App{
				Exec:             exec,
				User:             user,
				Group:            group,
				Environment:      env,
				WorkingDirectory: dockerConfig.WorkingDir,
			}

			app.MountPoints, err = convertVolumesToMPs(dockerConfig.Volumes)
			if err != nil {
				return nil, err
			}

			app.Ports, err = convertPorts(dockerConfig.ExposedPorts, dockerConfig.PortSpecs)
			if err != nil {
				return nil, err
			}

			ep, cmd, err := generateEPCmdAnnotation(dockerConfig.Entrypoint, dockerConfig.Cmd)
			if err != nil {
				return nil, err
			}
			if len(ep) > 0 {
				addAnno(common.AppcDockerEntrypoint, ep)
			}
			if len(cmd) > 0 {
				addAnno(common.AppcDockerCmd, cmd)
			}

			genManifest.App = app
		}
	}

	if layerData.Parent != "" {
		indexPrefix := ""
		// omit docker hub index URL in app name
		indexPrefix = dockerURL.IndexURL + "/"
		parentImageNameString := indexPrefix + dockerURL.ImageName + "-" + layerData.Parent
		parentImageNameString, err := appctypes.SanitizeACIdentifier(parentImageNameString)
		if err != nil {
			return nil, err
		}
		parentImageName := appctypes.MustACIdentifier(parentImageNameString)

		plbl, err := appctypes.LabelsFromMap(labels)
		if err != nil {
			return nil, err
		}

		genManifest.Dependencies = append(genManifest.Dependencies, appctypes.Dependency{ImageName: *parentImageName, Labels: plbl})

		addAnno(common.AppcDockerTag, dockerURL.Tag)
	}

	genManifest.Labels, err = appctypes.LabelsFromMap(labels)
	if err != nil {
		return nil, err
	}
	genManifest.Annotations = annotations

	return genManifest, nil
}