diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 2 | ||||
-rw-r--r-- | libpod/container_inspect.go | 83 | ||||
-rw-r--r-- | libpod/define/annotations.go | 68 | ||||
-rw-r--r-- | libpod/define/containerstate.go | 19 | ||||
-rw-r--r-- | libpod/image/manifests.go | 56 | ||||
-rw-r--r-- | libpod/info.go | 7 | ||||
-rw-r--r-- | libpod/kube.go | 2 | ||||
-rw-r--r-- | libpod/pod.go | 10 | ||||
-rw-r--r-- | libpod/runtime_img.go | 2 | ||||
-rw-r--r-- | libpod/stats.go | 4 | ||||
-rw-r--r-- | libpod/stats_config.go | 20 | ||||
-rw-r--r-- | libpod/stats_unsupported.go | 2 | ||||
-rw-r--r-- | libpod/util.go | 20 | ||||
-rw-r--r-- | libpod/util_test.go | 3 | ||||
-rw-r--r-- | libpod/volume.go | 13 |
15 files changed, 183 insertions, 128 deletions
diff --git a/libpod/container.go b/libpod/container.go index 5cd719ab6..d4a779b13 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -1221,5 +1221,5 @@ func (c *Container) AutoRemove() bool { if spec.Annotations == nil { return false } - return c.Spec().Annotations[InspectAnnotationAutoremove] == InspectResponseTrue + return c.Spec().Annotations[define.InspectAnnotationAutoremove] == define.InspectResponseTrue } diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 276429b11..ae28dde94 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -16,73 +16,6 @@ import ( "github.com/syndtr/gocapability/capability" ) -const ( - // InspectAnnotationCIDFile is used by Inspect to determine if a - // container ID file was created for the container. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationCIDFile = "io.podman.annotations.cid-file" - // InspectAnnotationAutoremove is used by Inspect to determine if a - // container will be automatically removed on exit. - // If an annotation with this key is found in the OCI spec and is one of - // the two supported boolean values (InspectResponseTrue and - // InspectResponseFalse) it will be used in the output of Inspect(). - InspectAnnotationAutoremove = "io.podman.annotations.autoremove" - // InspectAnnotationVolumesFrom is used by Inspect to identify - // containers whose volumes are are being used by this container. - // It is expected to be a comma-separated list of container names and/or - // IDs. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationVolumesFrom = "io.podman.annotations.volumes-from" - // InspectAnnotationPrivileged is used by Inspect to identify containers - // which are privileged (IE, running with elevated privileges). - // It is expected to be a boolean, populated by one of - // InspectResponseTrue or InspectResponseFalse. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationPrivileged = "io.podman.annotations.privileged" - // InspectAnnotationPublishAll is used by Inspect to identify containers - // which have all the ports from their image published. - // It is expected to be a boolean, populated by one of - // InspectResponseTrue or InspectResponseFalse. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationPublishAll = "io.podman.annotations.publish-all" - // InspectAnnotationInit is used by Inspect to identify containers that - // mount an init binary in. - // It is expected to be a boolean, populated by one of - // InspectResponseTrue or InspectResponseFalse. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationInit = "io.podman.annotations.init" - // InspectAnnotationLabel is used by Inspect to identify containers with - // special SELinux-related settings. It is used to populate the output - // of the SecurityOpt setting. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationLabel = "io.podman.annotations.label" - // InspectAnnotationSeccomp is used by Inspect to identify containers - // with special Seccomp-related settings. It is used to populate the - // output of the SecurityOpt setting in Inspect. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationSeccomp = "io.podman.annotations.seccomp" - // InspectAnnotationApparmor is used by Inspect to identify containers - // with special Apparmor-related settings. It is used to populate the - // output of the SecurityOpt setting. - // If an annotation with this key is found in the OCI spec, it will be - // used in the output of Inspect(). - InspectAnnotationApparmor = "io.podman.annotations.apparmor" - - // InspectResponseTrue is a boolean True response for an inspect - // annotation. - InspectResponseTrue = "TRUE" - // InspectResponseFalse is a boolean False response for an inspect - // annotation. - InspectResponseFalse = "FALSE" -) - // inspectLocked inspects a container for low-level information. // The caller must held c.lock. func (c *Container) inspectLocked(size bool) (*define.InspectContainerData, error) { @@ -452,26 +385,26 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named // Annotations if ctrSpec.Annotations != nil { - hostConfig.ContainerIDFile = ctrSpec.Annotations[InspectAnnotationCIDFile] - if ctrSpec.Annotations[InspectAnnotationAutoremove] == InspectResponseTrue { + hostConfig.ContainerIDFile = ctrSpec.Annotations[define.InspectAnnotationCIDFile] + if ctrSpec.Annotations[define.InspectAnnotationAutoremove] == define.InspectResponseTrue { hostConfig.AutoRemove = true } - if ctrs, ok := ctrSpec.Annotations[InspectAnnotationVolumesFrom]; ok { + if ctrs, ok := ctrSpec.Annotations[define.InspectAnnotationVolumesFrom]; ok { hostConfig.VolumesFrom = strings.Split(ctrs, ",") } - if ctrSpec.Annotations[InspectAnnotationPrivileged] == InspectResponseTrue { + if ctrSpec.Annotations[define.InspectAnnotationPrivileged] == define.InspectResponseTrue { hostConfig.Privileged = true } - if ctrSpec.Annotations[InspectAnnotationInit] == InspectResponseTrue { + if ctrSpec.Annotations[define.InspectAnnotationInit] == define.InspectResponseTrue { hostConfig.Init = true } - if label, ok := ctrSpec.Annotations[InspectAnnotationLabel]; ok { + if label, ok := ctrSpec.Annotations[define.InspectAnnotationLabel]; ok { hostConfig.SecurityOpt = append(hostConfig.SecurityOpt, fmt.Sprintf("label=%s", label)) } - if seccomp, ok := ctrSpec.Annotations[InspectAnnotationSeccomp]; ok { + if seccomp, ok := ctrSpec.Annotations[define.InspectAnnotationSeccomp]; ok { hostConfig.SecurityOpt = append(hostConfig.SecurityOpt, fmt.Sprintf("seccomp=%s", seccomp)) } - if apparmor, ok := ctrSpec.Annotations[InspectAnnotationApparmor]; ok { + if apparmor, ok := ctrSpec.Annotations[define.InspectAnnotationApparmor]; ok { hostConfig.SecurityOpt = append(hostConfig.SecurityOpt, fmt.Sprintf("apparmor=%s", apparmor)) } } diff --git a/libpod/define/annotations.go b/libpod/define/annotations.go new file mode 100644 index 000000000..f6b1c06ea --- /dev/null +++ b/libpod/define/annotations.go @@ -0,0 +1,68 @@ +package define + +const ( + // InspectAnnotationCIDFile is used by Inspect to determine if a + // container ID file was created for the container. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationCIDFile = "io.podman.annotations.cid-file" + // InspectAnnotationAutoremove is used by Inspect to determine if a + // container will be automatically removed on exit. + // If an annotation with this key is found in the OCI spec and is one of + // the two supported boolean values (InspectResponseTrue and + // InspectResponseFalse) it will be used in the output of Inspect(). + InspectAnnotationAutoremove = "io.podman.annotations.autoremove" + // InspectAnnotationVolumesFrom is used by Inspect to identify + // containers whose volumes are are being used by this container. + // It is expected to be a comma-separated list of container names and/or + // IDs. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationVolumesFrom = "io.podman.annotations.volumes-from" + // InspectAnnotationPrivileged is used by Inspect to identify containers + // which are privileged (IE, running with elevated privileges). + // It is expected to be a boolean, populated by one of + // InspectResponseTrue or InspectResponseFalse. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationPrivileged = "io.podman.annotations.privileged" + // InspectAnnotationPublishAll is used by Inspect to identify containers + // which have all the ports from their image published. + // It is expected to be a boolean, populated by one of + // InspectResponseTrue or InspectResponseFalse. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationPublishAll = "io.podman.annotations.publish-all" + // InspectAnnotationInit is used by Inspect to identify containers that + // mount an init binary in. + // It is expected to be a boolean, populated by one of + // InspectResponseTrue or InspectResponseFalse. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationInit = "io.podman.annotations.init" + // InspectAnnotationLabel is used by Inspect to identify containers with + // special SELinux-related settings. It is used to populate the output + // of the SecurityOpt setting. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationLabel = "io.podman.annotations.label" + // InspectAnnotationSeccomp is used by Inspect to identify containers + // with special Seccomp-related settings. It is used to populate the + // output of the SecurityOpt setting in Inspect. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationSeccomp = "io.podman.annotations.seccomp" + // InspectAnnotationApparmor is used by Inspect to identify containers + // with special Apparmor-related settings. It is used to populate the + // output of the SecurityOpt setting. + // If an annotation with this key is found in the OCI spec, it will be + // used in the output of Inspect(). + InspectAnnotationApparmor = "io.podman.annotations.apparmor" + + // InspectResponseTrue is a boolean True response for an inspect + // annotation. + InspectResponseTrue = "TRUE" + // InspectResponseFalse is a boolean False response for an inspect + // annotation. + InspectResponseFalse = "FALSE" +) diff --git a/libpod/define/containerstate.go b/libpod/define/containerstate.go index 6da49a594..825e77387 100644 --- a/libpod/define/containerstate.go +++ b/libpod/define/containerstate.go @@ -112,3 +112,22 @@ func (s ContainerExecStatus) String() string { return "bad state" } } + +// ContainerStats contains the statistics information for a running container +type ContainerStats struct { + ContainerID string + Name string + PerCPU []uint64 + CPU float64 + CPUNano uint64 + CPUSystemNano uint64 + SystemNano uint64 + MemUsage uint64 + MemLimit uint64 + MemPerc float64 + NetInput uint64 + NetOutput uint64 + BlockInput uint64 + BlockOutput uint64 + PIDs uint64 +} diff --git a/libpod/image/manifests.go b/libpod/image/manifests.go index 7ca17f86c..59678fdb2 100644 --- a/libpod/image/manifests.go +++ b/libpod/image/manifests.go @@ -24,6 +24,18 @@ type ManifestAddOpts struct { Variant string `json:"variant"` } +// ManifestAnnotateOptions defines the options for +// manifest annotate +type ManifestAnnotateOpts struct { + Annotation map[string]string `json:"annotation"` + Arch string `json:"arch"` + Features []string `json:"features"` + OS string `json:"os"` + OSFeatures []string `json:"os_feature"` + OSVersion string `json:"os_version"` + Variant string `json:"variant"` +} + // InspectManifest returns a dockerized version of the manifest list func (i *Image) InspectManifest() (*manifest.Schema2List, error) { list, err := i.getManifestList() @@ -158,3 +170,47 @@ func (i *Image) PushManifest(dest types.ImageReference, opts manifests.PushOptio _, d, err := list.Push(context.Background(), dest, opts) return d, err } + +// AnnotateManifest updates an image configuration of a manifest list. +func (i *Image) AnnotateManifest(systemContext types.SystemContext, d digest.Digest, opts ManifestAnnotateOpts) (string, error) { + list, err := i.getManifestList() + if err != nil { + return "", err + } + if len(opts.OS) > 0 { + if err := list.SetOS(d, opts.OS); err != nil { + return "", err + } + } + if len(opts.OSVersion) > 0 { + if err := list.SetOSVersion(d, opts.OSVersion); err != nil { + return "", err + } + } + if len(opts.Features) > 0 { + if err := list.SetFeatures(d, opts.Features); err != nil { + return "", err + } + } + if len(opts.OSFeatures) > 0 { + if err := list.SetOSFeatures(d, opts.OSFeatures); err != nil { + return "", err + } + } + if len(opts.Arch) > 0 { + if err := list.SetArchitecture(d, opts.Arch); err != nil { + return "", err + } + } + if len(opts.Variant) > 0 { + if err := list.SetVariant(d, opts.Variant); err != nil { + return "", err + } + } + if len(opts.Annotation) > 0 { + if err := list.SetAnnotations(&d, opts.Annotation); err != nil { + return "", err + } + } + return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "") +} diff --git a/libpod/info.go b/libpod/info.go index d7ed5bb16..4007e0ce7 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -198,9 +198,15 @@ func (r *Runtime) getContainerStoreInfo() (define.ContainerStore, error) { if err != nil { return cs, err } + cs.Number = len(cons) for _, con := range cons { state, err := con.State() if err != nil { + if errors.Cause(err) == define.ErrNoSuchCtr { + // container was probably removed + cs.Number-- + continue + } return cs, err } switch state { @@ -212,7 +218,6 @@ func (r *Runtime) getContainerStoreInfo() (define.ContainerStore, error) { stopped += 1 } } - cs.Number = len(cons) cs.Paused = paused cs.Stopped = stopped cs.Running = running diff --git a/libpod/kube.go b/libpod/kube.go index 5511d303d..a3c5e912f 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -469,7 +469,7 @@ func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) { } var selinuxOpts v1.SELinuxOptions - opts := strings.SplitN(c.config.Spec.Annotations[InspectAnnotationLabel], ":", 2) + opts := strings.SplitN(c.config.Spec.Annotations[define.InspectAnnotationLabel], ":", 2) if len(opts) == 2 { switch opts[0] { case "type": diff --git a/libpod/pod.go b/libpod/pod.go index b5a14c165..8eb06ae2f 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -247,14 +247,14 @@ func (p *Pod) InfraContainerID() (string, error) { // PodContainerStats is an organization struct for pods and their containers type PodContainerStats struct { Pod *Pod - ContainerStats map[string]*ContainerStats + ContainerStats map[string]*define.ContainerStats } // GetPodStats returns the stats for each of its containers -func (p *Pod) GetPodStats(previousContainerStats map[string]*ContainerStats) (map[string]*ContainerStats, error) { +func (p *Pod) GetPodStats(previousContainerStats map[string]*define.ContainerStats) (map[string]*define.ContainerStats, error) { var ( ok bool - prevStat *ContainerStats + prevStat *define.ContainerStats ) p.lock.Lock() defer p.lock.Unlock() @@ -266,10 +266,10 @@ func (p *Pod) GetPodStats(previousContainerStats map[string]*ContainerStats) (ma if err != nil { return nil, err } - newContainerStats := make(map[string]*ContainerStats) + newContainerStats := make(map[string]*define.ContainerStats) for _, c := range containers { if prevStat, ok = previousContainerStats[c.ID()]; !ok { - prevStat = &ContainerStats{} + prevStat = &define.ContainerStats{} } newStats, err := c.GetContainerStats(prevStat) // If the container wasn't running, don't include it diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 919080c42..cd7f54799 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -56,7 +56,7 @@ func (r *Runtime) RemoveImage(ctx context.Context, img *image.Image, force bool) } } } else { - return nil, fmt.Errorf("could not remove image %s as it is being used by %d containers", img.ID(), len(imageCtrs)) + return nil, errors.Wrapf(define.ErrImageInUse, "could not remove image %s as it is being used by %d containers", img.ID(), len(imageCtrs)) } } diff --git a/libpod/stats.go b/libpod/stats.go index 6f42afd18..9f4986144 100644 --- a/libpod/stats.go +++ b/libpod/stats.go @@ -13,8 +13,8 @@ import ( ) // GetContainerStats gets the running stats for a given container -func (c *Container) GetContainerStats(previousStats *ContainerStats) (*ContainerStats, error) { - stats := new(ContainerStats) +func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*define.ContainerStats, error) { + stats := new(define.ContainerStats) stats.ContainerID = c.ID() stats.Name = c.Name() diff --git a/libpod/stats_config.go b/libpod/stats_config.go deleted file mode 100644 index 91d3d1493..000000000 --- a/libpod/stats_config.go +++ /dev/null @@ -1,20 +0,0 @@ -package libpod - -// ContainerStats contains the statistics information for a running container -type ContainerStats struct { - ContainerID string - Name string - PerCPU []uint64 - CPU float64 - CPUNano uint64 - CPUSystemNano uint64 - SystemNano uint64 - MemUsage uint64 - MemLimit uint64 - MemPerc float64 - NetInput uint64 - NetOutput uint64 - BlockInput uint64 - BlockOutput uint64 - PIDs uint64 -} diff --git a/libpod/stats_unsupported.go b/libpod/stats_unsupported.go index ec19a89a1..6d21ae8f2 100644 --- a/libpod/stats_unsupported.go +++ b/libpod/stats_unsupported.go @@ -5,6 +5,6 @@ package libpod import "github.com/containers/libpod/libpod/define" // GetContainerStats gets the running stats for a given container -func (c *Container) GetContainerStats(previousStats *ContainerStats) (*ContainerStats, error) { +func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*define.ContainerStats, error) { return nil, define.ErrOSNotSupported } diff --git a/libpod/util.go b/libpod/util.go index 6457dac1c..bdfd153ed 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -9,12 +9,10 @@ import ( "os/exec" "path/filepath" "sort" - "strconv" "strings" "time" "github.com/containers/common/pkg/config" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/utils" "github.com/fsnotify/fsnotify" @@ -36,24 +34,6 @@ func FuncTimer(funcName string) { fmt.Printf("%s executed in %d ms\n", funcName, elapsed) } -// RemoveScientificNotationFromFloat returns a float without any -// scientific notation if the number has any. -// golang does not handle conversion of float64s that have scientific -// notation in them and otherwise stinks. please replace this if you have -// a better implementation. -func RemoveScientificNotationFromFloat(x float64) (float64, error) { - bigNum := strconv.FormatFloat(x, 'g', -1, 64) - breakPoint := strings.IndexAny(bigNum, "Ee") - if breakPoint > 0 { - bigNum = bigNum[:breakPoint] - } - result, err := strconv.ParseFloat(bigNum, 64) - if err != nil { - return x, errors.Wrapf(err, "unable to remove scientific number from calculations") - } - return result, nil -} - // MountExists returns true if dest exists in the list of mounts func MountExists(specMounts []spec.Mount, dest string) bool { for _, m := range specMounts { diff --git a/libpod/util_test.go b/libpod/util_test.go index 227686c2b..4e18a7e4e 100644 --- a/libpod/util_test.go +++ b/libpod/util_test.go @@ -3,6 +3,7 @@ package libpod import ( "testing" + "github.com/containers/libpod/utils" "github.com/stretchr/testify/assert" ) @@ -10,7 +11,7 @@ func TestRemoveScientificNotationFromFloat(t *testing.T) { numbers := []float64{0.0, .5, 1.99999932, 1.04e+10} results := []float64{0.0, .5, 1.99999932, 1.04} for i, x := range numbers { - result, err := RemoveScientificNotationFromFloat(x) + result, err := utils.RemoveScientificNotationFromFloat(x) assert.NoError(t, err) assert.Equal(t, result, results[i]) } diff --git a/libpod/volume.go b/libpod/volume.go index 70099d6f4..82f389833 100644 --- a/libpod/volume.go +++ b/libpod/volume.go @@ -3,6 +3,7 @@ package libpod import ( "time" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/lock" ) @@ -133,3 +134,15 @@ func (v *Volume) Config() (*VolumeConfig, error) { err := JSONDeepCopy(v.config, &config) return &config, err } + +// VolumeInUse goes through the container dependencies of a volume +// and checks if the volume is being used by any container. +func (v *Volume) VolumesInUse() ([]string, error) { + v.lock.Lock() + defer v.lock.Unlock() + + if !v.valid { + return nil, define.ErrVolumeRemoved + } + return v.runtime.state.VolumeInUse(v) +} |