diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 3f6668ef45..104509c1f5 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -184,6 +184,7 @@ func buildFlags(cmd *cobra.Command) { _ = flags.MarkHidden("compress") _ = flags.MarkHidden("output") _ = flags.MarkHidden("logsplit") + _ = flags.MarkHidden("cw") } } @@ -575,6 +576,14 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil } } + var confidentialWorkloadOptions buildahDefine.ConfidentialWorkloadOptions + if c.Flag("cw").Changed { + confidentialWorkloadOptions, err = parse.GetConfidentialWorkloadOptions(flags.CWOptions) + if err != nil { + return nil, err + } + } + opts := buildahDefine.BuildOptions{ AddCapabilities: flags.CapAdd, AdditionalTags: tags, @@ -587,6 +596,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil CacheFrom: cacheFrom, CacheTo: cacheTo, CacheTTL: cacheTTL, + ConfidentialWorkload: confidentialWorkloadOptions, CommonBuildOpts: commonOpts, Compression: compression, ConfigureNetwork: networkPolicy, @@ -605,6 +615,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil Isolation: isolation, Jobs: &flags.Jobs, Labels: flags.Label, + LayerLabels: flags.LayerLabel, Layers: flags.Layers, LogRusage: flags.LogRusage, LogFile: flags.Logfile, diff --git a/docs/source/markdown/podman-build.1.md.in b/docs/source/markdown/podman-build.1.md.in index d6ac53d504..4b2e423e25 100644 --- a/docs/source/markdown/podman-build.1.md.in +++ b/docs/source/markdown/podman-build.1.md.in @@ -222,6 +222,66 @@ Set additional flags to pass to the C Preprocessor cpp(1). Containerfiles ending @@option creds +#### **--cw**=*options* + +Produce an image suitable for use as a confidential workload running in a +trusted execution environment (TEE) using krun (i.e., *crun* built with the +libkrun feature enabled and invoked as *krun*). Instead of the conventional +contents, the root filesystem of the image will contain an encrypted disk image +and configuration information for krun. + +The value for *options* is a comma-separated list of key=value pairs, supplying +configuration information which is needed for producing the additional data +which will be included in the container image. + +Recognized _keys_ are: + +*attestation_url*: The location of a key broker / attestation server. +If a value is specified, the new image's workload ID, along with the passphrase +used to encrypt the disk image, will be registered with the server, and the +server's location will be stored in the container image. +At run-time, krun is expected to contact the server to retrieve the passphrase +using the workload ID, which is also stored in the container image. +If no value is specified, a *passphrase* value *must* be specified. + +*cpus*: The number of virtual CPUs which the image expects to be run with at +run-time. If not specified, a default value will be supplied. + +*firmware_library*: The location of the libkrunfw-sev shared library. If not +specified, `buildah` checks for its presence in a number of hard-coded +locations. + +*memory*: The amount of memory which the image expects to be run with at +run-time, as a number of megabytes. If not specified, a default value will be +supplied. + +*passphrase*: The passphrase to use to encrypt the disk image which will be +included in the container image. +If no value is specified, but an *attestation_url* value is specified, a +randomly-generated passphrase will be used. +The authors recommend setting an *attestation_url* but not a *passphrase*. + +*slop*: Extra space to allocate for the disk image compared to the size of the +container image's contents, expressed either as a percentage (..%) or a size +value (bytes, or larger units if suffixes like KB or MB are present), or a sum +of two or more such specifications. If not specified, `buildah` guesses that +25% more space than the contents will be enough, but this option is provided in +case its guess is wrong. + +*type*: The type of trusted execution environment (TEE) which the image should +be marked for use with. Accepted values are "SEV" (AMD Secure Encrypted +Virtualization - Encrypted State) and "SNP" (AMD Secure Encrypted +Virtualization - Secure Nested Paging). If not specified, defaults to "SNP". + +*workload_id*: A workload identifier which will be recorded in the container +image, to be used at run-time for retrieving the passphrase which was used to +encrypt the disk image. If not specified, a semi-random value will be derived +from the base image's image ID. + +This option is not supported on the remote client, including Mac and Windows +(excluding WSL2) machines. + + #### **--decryption-key**=*key[:passphrase]* The [key[:passphrase]] to be used for decryption of images. Key can point to @@ -396,6 +456,14 @@ capabilities is a subset of the default list. If the specified capabilities are not in the default set, Podman prints an error message and runs the container with the default capabilities. +#### **--layer-label**=*label[=value]* + +Add an intermediate image *label* (e.g. label=*value*) to the intermediate +image metadata. It can be used multiple times. + +If *label* is named, but neither `=` nor a `value` is provided, then +the *label* is set to an empty value. + #### **--layers** Cache intermediate images during the build process (Default is `true`). diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 8c492985a1..b639000966 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -108,6 +108,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Jobs int `schema:"jobs"` LabelOpts string `schema:"labelopts"` Labels string `schema:"labels"` + LayerLabels []string `schema:"layerLabel"` Layers bool `schema:"layers"` LogRusage bool `schema:"rusage"` Manifest string `schema:"manifest"` @@ -686,6 +687,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Isolation: isolation, Jobs: &jobs, Labels: labels, + LayerLabels: query.LayerLabels, Layers: query.Layers, LogRusage: query.LogRusage, Manifest: query.Manifest, diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 1abe5a98f5..5645052497 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -1552,6 +1552,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // JSON map of key, value pairs to set as labels on the new image // (As of version 1.xx) // - in: query + // name: layerLabel + // description: Add an intermediate image *label* (e.g. label=*value*) to the intermediate image metadata. + // type: array + // items: + // type: string + // - in: query // name: layers // type: boolean // default: true diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index 7778174c36..668484b715 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -217,6 +217,9 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO params.Set("apparmor", options.CommonBuildOpts.ApparmorProfile) } + for _, layerLabel := range options.LayerLabels { + params.Add("layerLabel", layerLabel) + } if options.Layers { params.Set("layers", "1") }