diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 7 | ||||
-rw-r--r-- | libpod/container_commit.go | 17 | ||||
-rw-r--r-- | libpod/container_inspect.go | 30 | ||||
-rw-r--r-- | libpod/container_internal.go | 2 | ||||
-rw-r--r-- | libpod/image/image.go | 10 | ||||
-rw-r--r-- | libpod/image/prune.go | 10 | ||||
-rw-r--r-- | libpod/image/pull.go | 2 | ||||
-rw-r--r-- | libpod/oci_conmon_linux.go | 37 | ||||
-rw-r--r-- | libpod/options.go | 17 | ||||
-rw-r--r-- | libpod/runtime_img.go | 13 |
10 files changed, 113 insertions, 32 deletions
diff --git a/libpod/container.go b/libpod/container.go index edf72f4ee..a046dcafc 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -379,6 +379,8 @@ type ContainerConfig struct { CgroupParent string `json:"cgroupParent"` // LogPath log location LogPath string `json:"logPath"` + // LogTag is the tag used for logging + LogTag string `json:"logTag"` // LogDriver driver for logs LogDriver string `json:"logDriver"` // File containing the conmon PID @@ -726,6 +728,11 @@ func (c *Container) LogPath() string { return c.config.LogPath } +// LogTag returns the tag to the container's log file +func (c *Container) LogTag() string { + return c.config.LogTag +} + // RestartPolicy returns the container's restart policy. func (c *Container) RestartPolicy() string { return c.config.RestartPolicy diff --git a/libpod/container_commit.go b/libpod/container_commit.go index a0ba57f4f..ccc23621e 100644 --- a/libpod/container_commit.go +++ b/libpod/container_commit.go @@ -8,6 +8,7 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/util" is "github.com/containers/image/v5/storage" + "github.com/containers/image/v5/types" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" @@ -32,6 +33,10 @@ type ContainerCommitOptions struct { // Commit commits the changes between a container and its image, creating a new // image func (c *Container) Commit(ctx context.Context, destImage string, options ContainerCommitOptions) (*image.Image, error) { + var ( + imageRef types.ImageReference + ) + if c.config.Rootfs != "" { return nil, errors.Errorf("cannot commit a container that uses an exploded rootfs") } @@ -71,7 +76,6 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai if err != nil { return nil, err } - if options.Author != "" { importBuilder.SetMaintainer(options.Author) } @@ -191,12 +195,11 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai if err != nil { return nil, errors.Wrapf(err, "error resolving name %q", destImage) } - if len(candidates) == 0 { - return nil, errors.Errorf("error parsing target image name %q", destImage) - } - imageRef, err := is.Transport.ParseStoreReference(c.runtime.store, candidates[0]) - if err != nil { - return nil, errors.Wrapf(err, "error parsing target image name %q", destImage) + if len(candidates) > 0 { + imageRef, err = is.Transport.ParseStoreReference(c.runtime.store, candidates[0]) + if err != nil { + return nil, errors.Wrapf(err, "error parsing target image name %q", destImage) + } } id, _, _, err := importBuilder.Commit(ctx, imageRef, commitOptions) if err != nil { diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 639dd6e91..3f4ab394f 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -107,6 +107,7 @@ type InspectContainerData struct { OCIConfigPath string `json:"OCIConfigPath,omitempty"` OCIRuntime string `json:"OCIRuntime,omitempty"` LogPath string `json:"LogPath"` + LogTag string `json:"LogTag"` ConmonPidFile string `json:"ConmonPidFile"` Name string `json:"Name"` RestartCount int32 `json:"RestartCount"` @@ -629,17 +630,9 @@ type InspectNetworkSettings struct { MacAddress string `json:"MacAddress"` } -// Inspect a container for low-level information -func (c *Container) Inspect(size bool) (*InspectContainerData, error) { - if !c.batched { - c.lock.Lock() - defer c.lock.Unlock() - - if err := c.syncContainer(); err != nil { - return nil, err - } - } - +// inspectLocked inspects a container for low-level information. +// The caller must held c.lock. +func (c *Container) inspectLocked(size bool) (*InspectContainerData, error) { storeCtr, err := c.runtime.store.Container(c.ID()) if err != nil { return nil, errors.Wrapf(err, "error getting container from store %q", c.ID()) @@ -655,6 +648,20 @@ func (c *Container) Inspect(size bool) (*InspectContainerData, error) { return c.getContainerInspectData(size, driverData) } +// Inspect a container for low-level information +func (c *Container) Inspect(size bool) (*InspectContainerData, error) { + if !c.batched { + c.lock.Lock() + defer c.lock.Unlock() + + if err := c.syncContainer(); err != nil { + return nil, err + } + } + + return c.inspectLocked(size) +} + func (c *Container) getContainerInspectData(size bool, driverData *driver.Data) (*InspectContainerData, error) { config := c.config runtimeInfo := c.state @@ -732,6 +739,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *driver.Data) HostsPath: hostsPath, StaticDir: config.StaticDir, LogPath: config.LogPath, + LogTag: config.LogTag, OCIRuntime: config.OCIRuntime, ConmonPidFile: config.ConmonPidFile, Name: config.Name, diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 562f783a7..46c83149a 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -1195,6 +1195,7 @@ func (c *Container) pause() error { } if err := c.ociRuntime.PauseContainer(c); err != nil { + // TODO when using docker-py there is some sort of race/incompatibility here return err } @@ -1212,6 +1213,7 @@ func (c *Container) unpause() error { } if err := c.ociRuntime.UnpauseContainer(c); err != nil { + // TODO when using docker-py there is some sort of race/incompatibility here return err } diff --git a/libpod/image/image.go b/libpod/image/image.go index c8583a1c5..bce10e24c 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -781,6 +781,7 @@ type History struct { CreatedBy string `json:"createdBy"` Size int64 `json:"size"` Comment string `json:"comment"` + Tags []string `json:"tags"` } // History gets the history of an image and the IDs of images that are part of @@ -840,14 +841,17 @@ func (i *Image) History(ctx context.Context) ([]*History, error) { delete(topLayerMap, layer.ID) } } - - allHistory = append(allHistory, &History{ + h := History{ ID: id, Created: oci.History[x].Created, CreatedBy: oci.History[x].CreatedBy, Size: size, Comment: oci.History[x].Comment, - }) + } + if layer != nil { + h.Tags = layer.Names + } + allHistory = append(allHistory, &h) if layer != nil && layer.Parent != "" && !oci.History[x].EmptyLayer { layer, err = i.imageruntime.store.Layer(layer.Parent) diff --git a/libpod/image/prune.go b/libpod/image/prune.go index f5be8ed50..3afff22af 100644 --- a/libpod/image/prune.go +++ b/libpod/image/prune.go @@ -116,6 +116,10 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ( return nil, errors.Wrap(err, "unable to get images to prune") } for _, p := range pruneImages { + repotags, err := p.RepoTags() + if err != nil { + return nil, err + } if err := p.Remove(ctx, true); err != nil { if errors.Cause(err) == storage.ErrImageUsedByContainer { logrus.Warnf("Failed to prune image %s as it is in use: %v", p.ID(), err) @@ -124,7 +128,11 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ( return nil, errors.Wrap(err, "failed to prune image") } defer p.newImageEvent(events.Prune) - prunedCids = append(prunedCids, p.ID()) + nameOrID := p.ID() + if len(repotags) > 0 { + nameOrID = repotags[0] + } + prunedCids = append(prunedCids, nameOrID) } return prunedCids, nil } diff --git a/libpod/image/pull.go b/libpod/image/pull.go index 326a23f4c..76294ba06 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -407,5 +407,5 @@ func checkRemoteImageForLabel(ctx context.Context, label string, imageInfo pullR return nil } } - return errors.Errorf("%s has no label %s", imageInfo.image, label) + return errors.Errorf("%s has no label %s in %q", imageInfo.image, label, remoteInspect.Labels) } diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index b09dc3a4f..3b0b7bc7b 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" "syscall" + "text/template" "time" "github.com/containers/libpod/libpod/config" @@ -532,7 +533,7 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options if logrus.GetLevel() != logrus.DebugLevel && r.supportsJSON { ociLog = c.execOCILog(sessionID) } - args := r.sharedConmonArgs(c, sessionID, c.execBundlePath(sessionID), c.execPidPath(sessionID), c.execLogPath(sessionID), c.execExitFileDir(sessionID), ociLog) + args := r.sharedConmonArgs(c, sessionID, c.execBundlePath(sessionID), c.execPidPath(sessionID), c.execLogPath(sessionID), c.execExitFileDir(sessionID), ociLog, "") if options.PreserveFDs > 0 { args = append(args, formatRuntimeOpts("--preserve-fds", fmt.Sprintf("%d", options.PreserveFDs))...) @@ -890,6 +891,27 @@ func waitPidStop(pid int, timeout time.Duration) error { } } +func (r *ConmonOCIRuntime) getLogTag(ctr *Container) (string, error) { + logTag := ctr.LogTag() + if logTag == "" { + return "", nil + } + data, err := ctr.inspectLocked(false) + if err != nil { + return "", nil + } + tmpl, err := template.New("container").Parse(logTag) + if err != nil { + return "", errors.Wrapf(err, "template parsing error %s", logTag) + } + var b bytes.Buffer + err = tmpl.Execute(&b, data) + if err != nil { + return "", err + } + return b.String(), nil +} + // createOCIContainer generates this container's main conmon instance and prepares it for starting func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) (err error) { var stderrBuf bytes.Buffer @@ -916,7 +938,13 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co if logrus.GetLevel() != logrus.DebugLevel && r.supportsJSON { ociLog = filepath.Join(ctr.state.RunDir, "oci-log") } - args := r.sharedConmonArgs(ctr, ctr.ID(), ctr.bundlePath(), filepath.Join(ctr.state.RunDir, "pidfile"), ctr.LogPath(), r.exitsDir, ociLog) + + logTag, err := r.getLogTag(ctr) + if err != nil { + return err + } + + args := r.sharedConmonArgs(ctr, ctr.ID(), ctr.bundlePath(), filepath.Join(ctr.state.RunDir, "pidfile"), ctr.LogPath(), r.exitsDir, ociLog, logTag) if ctr.config.Spec.Process.Terminal { args = append(args, "-t") @@ -1150,7 +1178,7 @@ func (r *ConmonOCIRuntime) configureConmonEnv(runtimeDir string) ([]string, []*o } // sharedConmonArgs takes common arguments for exec and create/restore and formats them for the conmon CLI -func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, pidPath, logPath, exitDir, ociLogPath string) []string { +func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, pidPath, logPath, exitDir, ociLogPath, logTag string) []string { // set the conmon API version to be able to use the correct sync struct keys args := []string{"--api-version", "1"} if r.cgroupManager == define.SystemdCgroupsManager && !ctr.config.NoCgroups { @@ -1197,6 +1225,9 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p if ociLogPath != "" { args = append(args, "--runtime-arg", "--log-format=json", "--runtime-arg", "--log", fmt.Sprintf("--runtime-arg=%s", ociLogPath)) } + if logTag != "" { + args = append(args, "--log-tag", logTag) + } if ctr.config.NoCgroups { logrus.Debugf("Running with no CGroups") args = append(args, "--runtime-arg", "--cgroup-manager", "--runtime-arg", "disabled") diff --git a/libpod/options.go b/libpod/options.go index 031f4f705..1d6863e7b 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1059,6 +1059,23 @@ func WithLogPath(path string) CtrCreateOption { } } +// WithLogTag sets the tag to the log file. +func WithLogTag(tag string) CtrCreateOption { + return func(ctr *Container) error { + if ctr.valid { + return define.ErrCtrFinalized + } + if tag == "" { + return errors.Wrapf(define.ErrInvalidArg, "log tag must be set") + } + + ctr.config.LogTag = tag + + return nil + } + +} + // WithNoCgroups disables the creation of CGroups for the new container. func WithNoCgroups() CtrCreateOption { return func(ctr *Container) error { diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 9943c4104..bae1c1ed8 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -10,6 +10,7 @@ import ( "os" "github.com/containers/buildah/imagebuildah" + "github.com/containers/image/v5/docker/reference" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/util" @@ -145,9 +146,9 @@ func removeStorageContainers(ctrIDs []string, store storage.Store) error { } // Build adds the runtime to the imagebuildah call -func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, dockerfiles ...string) error { - _, _, err := imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...) - return err +func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, dockerfiles ...string) (string, reference.Canonical, error) { + id, ref, err := imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...) + return id, ref, err } // Import is called as an intermediary to the image library Import @@ -192,7 +193,7 @@ func (r *Runtime) Import(ctx context.Context, source string, reference string, c } // if it's stdin, buffer it, too if source == "-" { - file, err := downloadFromFile(os.Stdin) + file, err := DownloadFromFile(os.Stdin) if err != nil { return "", err } @@ -232,9 +233,9 @@ func downloadFromURL(source string) (string, error) { return outFile.Name(), nil } -// donwloadFromFile reads all of the content from the reader and temporarily +// DownloadFromFile reads all of the content from the reader and temporarily // saves in it /var/tmp/importxyz, which is deleted after the image is imported -func downloadFromFile(reader *os.File) (string, error) { +func DownloadFromFile(reader *os.File) (string, error) { outFile, err := ioutil.TempFile("/var/tmp", "import") if err != nil { return "", errors.Wrap(err, "error creating file") |