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 }
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 }
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 }
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 }
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) }
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 }
// 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 }