summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container.go7
-rw-r--r--libpod/container_commit.go17
-rw-r--r--libpod/container_inspect.go30
-rw-r--r--libpod/container_internal.go2
-rw-r--r--libpod/image/image.go10
-rw-r--r--libpod/image/prune.go10
-rw-r--r--libpod/image/pull.go2
-rw-r--r--libpod/oci_conmon_linux.go37
-rw-r--r--libpod/options.go17
-rw-r--r--libpod/runtime_img.go13
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")