func init() { v, err := types.NewSemVer(version) if err != nil { panic(err) } AppContainerVersion = *v }
// generatePodManifest creates the pod manifest from the command line input. // It returns the pod manifest as []byte on success. // This is invoked if no pod manifest is specified at the command line. func generatePodManifest(cfg PrepareConfig, dir string) ([]byte, error) { pm := schema.PodManifest{ ACKind: "PodManifest", Apps: make(schema.AppList, 0), } v, err := types.NewSemVer(version.Version) if err != nil { return nil, fmt.Errorf("error creating version: %v", err) } pm.ACVersion = *v if err := cfg.Apps.Walk(func(app *apps.App) error { img := app.ImageID am, err := cfg.Store.GetImageManifest(img.String()) if err != nil { return fmt.Errorf("error getting the manifest: %v", err) } appName, err := imageNameToAppName(am.Name) if err != nil { return fmt.Errorf("error converting image name to app name: %v", err) } if err := prepareAppImage(cfg, *appName, img, dir, cfg.UseOverlay); err != nil { return fmt.Errorf("error setting up image %s: %v", img, err) } if pm.Apps.Get(*appName) != nil { return fmt.Errorf("error: multiple apps with name %s", am.Name) } if am.App == nil { return fmt.Errorf("error: image %s has no app section", img) } ra := schema.RuntimeApp{ // TODO(vc): leverage RuntimeApp.Name for disambiguating the apps Name: *appName, App: am.App, Image: schema.RuntimeImage{ Name: &am.Name, ID: img, }, Annotations: am.Annotations, } if execOverride := app.Exec; execOverride != "" { ra.App.Exec = []string{execOverride} } if execAppends := app.Args; execAppends != nil { ra.App.Exec = append(ra.App.Exec, execAppends...) } if cfg.InheritEnv || len(cfg.ExplicitEnv) > 0 { MergeEnvs(&ra.App.Environment, cfg.InheritEnv, cfg.ExplicitEnv) } pm.Apps = append(pm.Apps, ra) return nil }); err != nil { return nil, err } // TODO(jonboulle): check that app mountpoint expectations are // satisfied here, rather than waiting for stage1 pm.Volumes = cfg.Volumes pm.Ports = cfg.Ports pmb, err := json.Marshal(pm) if err != nil { return nil, fmt.Errorf("error marshalling pod manifest: %v", err) } return pmb, nil }
func GenerateManifest(layerData types.DockerImageData, dockerURL *types.ParsedDockerURL) (*schema.ImageManifest, error) { dockerConfig := layerData.Config genManifest := &schema.ImageManifest{} appURL := "" // omit docker hub index URL in app name if dockerURL.IndexURL != defaultIndex { 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(schemaVersion) if err != nil { panic("invalid appc spec version") } genManifest.ACVersion = *acVersion genManifest.ACKind = appctypes.ACKind(schema.ImageManifestKind) var ( labels appctypes.Labels parentLabels appctypes.Labels annotations appctypes.Annotations ) layer := appctypes.MustACIdentifier("layer") labels = append(labels, appctypes.Label{Name: *layer, Value: layerData.ID}) tag := dockerURL.Tag version := appctypes.MustACIdentifier("version") labels = append(labels, appctypes.Label{Name: *version, Value: tag}) if layerData.OS != "" { os := appctypes.MustACIdentifier("os") labels = append(labels, appctypes.Label{Name: *os, Value: layerData.OS}) parentLabels = append(parentLabels, appctypes.Label{Name: *os, Value: layerData.OS}) if layerData.Architecture != "" { arch := appctypes.MustACIdentifier("arch") parentLabels = append(parentLabels, appctypes.Label{Name: *arch, Value: layerData.Architecture}) } } if layerData.Author != "" { authorsKey := appctypes.MustACIdentifier("authors") annotations = append(annotations, appctypes.Annotation{Name: *authorsKey, Value: layerData.Author}) } epoch := time.Unix(0, 0) if !layerData.Created.Equal(epoch) { createdKey := appctypes.MustACIdentifier("created") annotations = append(annotations, appctypes.Annotation{Name: *createdKey, Value: layerData.Created.Format(time.RFC3339)}) } if layerData.Comment != "" { commentKey := appctypes.MustACIdentifier("docker-comment") annotations = append(annotations, appctypes.Annotation{Name: *commentKey, Value: layerData.Comment}) } genManifest.Labels = labels genManifest.Annotations = annotations 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 } genManifest.App = app } } if layerData.Parent != "" { parentImageNameString := dockerURL.IndexURL + "/" + dockerURL.ImageName + "-" + layerData.Parent parentImageNameString, err := appctypes.SanitizeACIdentifier(parentImageNameString) if err != nil { return nil, err } parentImageName := appctypes.MustACIdentifier(parentImageNameString) genManifest.Dependencies = append(genManifest.Dependencies, appctypes.Dependency{ImageName: *parentImageName, Labels: parentLabels}) } return genManifest, nil }
func GenerateManifest(layerData types.DockerImageData, dockerURL *types.ParsedDockerURL) (*schema.ImageManifest, error) { dockerConfig := layerData.Config genManifest := &schema.ImageManifest{} appURL := "" // omit docker hub index URL in app name if dockerURL.IndexURL != defaultIndex { appURL = dockerURL.IndexURL + "/" } appURL += dockerURL.ImageName + "-" + layerData.ID appURL, err := appctypes.SanitizeACName(appURL) if err != nil { return nil, err } name, err := appctypes.NewACName(appURL) if err != nil { return nil, err } genManifest.Name = *name acVersion, err := appctypes.NewSemVer(schemaVersion) if err != nil { panic("invalid appc spec version") } genManifest.ACVersion = *acVersion genManifest.ACKind = appctypes.ACKind(schema.ImageManifestKind) var labels appctypes.Labels var parentLabels appctypes.Labels layer, _ := appctypes.NewACName("layer") labels = append(labels, appctypes.Label{Name: *layer, Value: layerData.ID}) tag := dockerURL.Tag version, _ := appctypes.NewACName("version") labels = append(labels, appctypes.Label{Name: *version, Value: tag}) if layerData.OS != "" { os, _ := appctypes.NewACName("os") labels = append(labels, appctypes.Label{Name: *os, Value: layerData.OS}) parentLabels = append(parentLabels, appctypes.Label{Name: *os, Value: layerData.OS}) if layerData.Architecture != "" { arch, _ := appctypes.NewACName("arch") parentLabels = append(parentLabels, appctypes.Label{Name: *arch, Value: layerData.Architecture}) } } genManifest.Labels = labels 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, } genManifest.App = app } } if layerData.Parent != "" { parentAppNameString := dockerURL.IndexURL + "/" + dockerURL.ImageName + "-" + layerData.Parent parentAppNameString, err := appctypes.SanitizeACName(parentAppNameString) if err != nil { return nil, err } parentAppName, err := appctypes.NewACName(parentAppNameString) if err != nil { return nil, err } genManifest.Dependencies = append(genManifest.Dependencies, appctypes.Dependency{App: *parentAppName, Labels: parentLabels}) } return genManifest, nil }