spiegel_podman/cmd/podman/commit.go
Matthew Heon ab7e2a6956 Store user Volumes, Entrypoint, Command in database
We need these for commit, and they cannot be properly deduced
from just the OCI spec, so save them in the database so we can
retrieve them for commit.

Signed-off-by: Matthew Heon <matthew.heon@gmail.com>

Closes: #700
Approved by: rhatdan
2018-05-03 12:23:12 +00:00

129 lines
3.5 KiB
Go

package main
import (
"fmt"
"io"
"os"
"strings"
"github.com/pkg/errors"
"github.com/projectatomic/buildah"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image"
"github.com/projectatomic/libpod/pkg/util"
"github.com/urfave/cli"
)
var (
commitFlags = []cli.Flag{
cli.StringSliceFlag{
Name: "change, c",
Usage: "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR",
},
cli.StringFlag{
Name: "format, f",
Usage: "`format` of the image manifest and metadata",
Value: "oci",
},
cli.StringFlag{
Name: "message, m",
Usage: "Set commit message for imported image",
},
cli.StringFlag{
Name: "author, a",
Usage: "Set the author for the image comitted",
},
cli.BoolTFlag{
Name: "pause, p",
Usage: "Pause container during commit",
},
cli.BoolFlag{
Name: "quiet, q",
Usage: "Suppress output",
},
}
commitDescription = `Create an image from a container's changes.
Optionally tag the image created, set the author with the --author flag,
set the commit message with the --message flag,
and make changes to the instructions with the --change flag.`
commitCommand = cli.Command{
Name: "commit",
Usage: "Create new image based on the changed container",
Description: commitDescription,
Flags: commitFlags,
Action: commitCmd,
ArgsUsage: "CONTAINER [REPOSITORY[:TAG]]",
}
)
func commitCmd(c *cli.Context) error {
if err := validateFlags(c, commitFlags); err != nil {
return err
}
runtime, err := libpodruntime.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
var (
writer io.Writer
mimeType string
)
args := c.Args()
if len(args) != 2 {
return errors.Errorf("you must provide a container name or ID and a target image name")
}
switch c.String("format") {
case "oci":
mimeType = buildah.OCIv1ImageManifest
if c.IsSet("message") {
return errors.Errorf("messages cannot be added to the OCIv1 image format.")
}
case "docker":
mimeType = buildah.Dockerv2ImageManifest
default:
return errors.Errorf("unrecognized image format %q", c.String("format"))
}
container := args[0]
reference := args[1]
if c.IsSet("change") {
for _, change := range c.StringSlice("change") {
splitChange := strings.Split(strings.ToUpper(change), "=")
if !util.StringInSlice(splitChange[0], []string{"CMD", "ENTRYPOINT", "ENV", "EXPOSE", "LABEL", "STOPSIGNAL", "USER", "VOLUME", "WORKDIR"}) {
return errors.Errorf("invalid syntax for --change ", change)
}
}
}
if !c.Bool("quiet") {
writer = os.Stderr
}
ctr, err := runtime.LookupContainer(container)
if err != nil {
return errors.Wrapf(err, "error looking up container %q", container)
}
sc := image.GetSystemContext(runtime.GetConfig().SignaturePolicyPath, "", false)
coptions := buildah.CommitOptions{
SignaturePolicyPath: runtime.GetConfig().SignaturePolicyPath,
ReportWriter: writer,
SystemContext: sc,
PreferredManifestType: mimeType,
}
options := libpod.ContainerCommitOptions{
CommitOptions: coptions,
Pause: c.Bool("pause"),
Message: c.String("message"),
Changes: c.StringSlice("change"),
Author: c.String("author"),
}
newImage, err := ctr.Commit(getContext(), reference, options)
if err != nil {
return err
}
fmt.Println(newImage.ID())
return nil
}