system df: fix image-size calculations

Fix two bugs in `system df`:

1.  The total size was calculated incorrectly as it was creating the sum
    of all image sizes but did not consider that a) the same image may
    be listed more than once (i.e., for each repo-tag pair), and that
    b) images share layers.

    The total size is now calculated directly in `libimage` by taking
    multi-layer use into account.

2.  The reclaimable size was calculated incorrectly.  This number
    indicates which data we can actually remove which means the total
    size minus what containers use (i.e., the "unique" size of the image
    in use by containers).

NOTE: The c/storage version is pinned back to the previous commit as it
      is buggy.  c/common already requires the buggy version, so use a
      `replace` to force/pin.

Fixes: #16135
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2022-10-17 16:53:48 +02:00
parent 2fb7218e63
commit 34235b2726
50 changed files with 284 additions and 210 deletions

View File

@ -65,24 +65,27 @@ func printSummary(cmd *cobra.Command, reports *entities.SystemDfReport) error {
var (
dfSummaries []*dfSummary
active int
size, reclaimable int64
used int64
)
visitedImages := make(map[string]bool)
for _, i := range reports.Images {
if _, ok := visitedImages[i.ImageID]; ok {
continue
}
visitedImages[i.ImageID] = true
if i.Containers > 0 {
active++
}
size += i.Size
if i.Containers < 1 {
reclaimable += i.Size
used += i.UniqueSize
}
}
imageSummary := dfSummary{
Type: "Images",
Total: len(reports.Images),
Active: active,
RawSize: size,
RawReclaimable: reclaimable,
RawSize: reports.ImagesSize, // The "raw" size is the sum of all layer sizes
RawReclaimable: reports.ImagesSize - used, // We can reclaim the date of "unused" images (i.e., the ones without containers)
}
dfSummaries = append(dfSummaries, &imageSummary)

8
go.mod
View File

@ -12,12 +12,12 @@ require (
github.com/containernetworking/cni v1.1.2
github.com/containernetworking/plugins v1.1.1
github.com/containers/buildah v1.28.0
github.com/containers/common v0.50.2-0.20221014181637-a6a9c521b6a5
github.com/containers/common v0.50.2-0.20221018104440-95c452ec992c
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.23.1-0.20221015133641-1921a1993c67
github.com/containers/ocicrypt v1.1.6
github.com/containers/psgo v1.8.0
github.com/containers/storage v1.43.1-0.20221014174544-ebf857fda6f3
github.com/containers/storage v1.43.1-0.20221018232308-33c396d1aacf
github.com/coreos/go-systemd/v22 v22.4.0
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
github.com/cyphar/filepath-securejoin v0.2.3
@ -79,7 +79,7 @@ require (
github.com/chzyer/readline v1.5.1 // indirect
github.com/containerd/cgroups v1.0.4 // indirect
github.com/containerd/containerd v1.6.8 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.12.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.12.1 // indirect
github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a // indirect
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@ -147,3 +147,5 @@ require (
)
replace github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc
replace github.com/containers/storage => github.com/containers/storage v1.43.1-0.20221014174544-ebf857fda6f3

16
go.sum
View File

@ -129,7 +129,6 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
@ -142,7 +141,6 @@ github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0=
github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.9.3/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
@ -377,9 +375,9 @@ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFY
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0=
github.com/containerd/stargz-snapshotter/estargz v0.12.0 h1:idtwRTLjk2erqiYhPWy2L844By8NRFYEwYHcXhoIWPM=
github.com/containerd/stargz-snapshotter/estargz v0.12.0/go.mod h1:AIQ59TewBFJ4GOPEQXujcrJ/EKxh5xXZegW1rkR1P/M=
github.com/containerd/stargz-snapshotter/estargz v0.12.1 h1:+7nYmHJb0tEkcRaAW+MHqoKaJYZmkikupxCqVtmPuY0=
github.com/containerd/stargz-snapshotter/estargz v0.12.1/go.mod h1:12VUuCq3qPq4y8yUW+l5w3+oXV3cx2Po3KSe/SmPGqw=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
@ -410,12 +408,11 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19
github.com/containers/buildah v1.28.0 h1:63Kpf9nAEJGsDEOArb5Q0dn5S3B9wFQc9kST4nU7+Pw=
github.com/containers/buildah v1.28.0/go.mod h1:pTYSfpf+Ha/KbnMmwhhhEjkSF3NuhpxZfiDNDORLgqY=
github.com/containers/common v0.50.1/go.mod h1:XnWlXPyE9Ky+8v8MfYWJZFnejkprAkUeo0DTWmSiwcY=
github.com/containers/common v0.50.2-0.20221014181637-a6a9c521b6a5 h1:Sp6lus6zXyg+Fv3ecoPOXm+80xC23YrKtntqYQU1pCA=
github.com/containers/common v0.50.2-0.20221014181637-a6a9c521b6a5/go.mod h1:7AM52N4n4UHzAeArB1vmIw7NhDNpDxrFaycubysYgFo=
github.com/containers/common v0.50.2-0.20221018104440-95c452ec992c h1:ZFMv4o5Mx8iq2O0AuE9sH4uiKqYggkdJPsz3KY65aGg=
github.com/containers/common v0.50.2-0.20221018104440-95c452ec992c/go.mod h1:71Q12SyFJO8rWgdMjvR6MC73KGpIpQU6PPkBRgoSots=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.23.0/go.mod h1:EXFFGEsL99S6aqLqK2mQJ3yrNh6Q05UCHt4mhF9JNoM=
github.com/containers/image/v5 v5.23.1-0.20221013202101-87afcefe9766/go.mod h1:2JJxA5K1NFpA3FtrK+Csmdlj++5oveB7CsXhekEJsIU=
github.com/containers/image/v5 v5.23.1-0.20221015133641-1921a1993c67 h1:kCKq/UASl4o6mwlqbBP8r+6fMIdQg3RkC2znw6H65A4=
github.com/containers/image/v5 v5.23.1-0.20221015133641-1921a1993c67/go.mod h1:V+wF8uIye+czYC4HWHGh4IK9dZBTsQUG1ZYie9gXxCQ=
github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU=
@ -430,9 +427,6 @@ github.com/containers/ocicrypt v1.1.6 h1:uoG52u2e91RE4UqmBICZY8dNshgfvkdl3BW6jnx
github.com/containers/ocicrypt v1.1.6/go.mod h1:WgjxPWdTJMqYMjf3M6cuIFFA1/MpyyhIM99YInA+Rvc=
github.com/containers/psgo v1.8.0 h1:2loGekmGAxM9ir5OsXWEfGwFxorMPYnc6gEDsGFQvhY=
github.com/containers/psgo v1.8.0/go.mod h1:T8ZxnX3Ur4RvnhxFJ7t8xJ1F48RhiZB4rSrOaR/qGHc=
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s=
github.com/containers/storage v1.43.1-0.20221014072257-a144fee6f51c/go.mod h1:K2qol6lCT/LRqZ3TMNRBU22tCTC6/Mb4G23K5SHhrYw=
github.com/containers/storage v1.43.1-0.20221014174544-ebf857fda6f3 h1:3jBfOfHFmaubuvhKSgfV7Krr2ZNpOlGiU9OhQYkoTxY=
github.com/containers/storage v1.43.1-0.20221014174544-ebf857fda6f3/go.mod h1:K2qol6lCT/LRqZ3TMNRBU22tCTC6/Mb4G23K5SHhrYw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@ -1411,7 +1405,6 @@ github.com/opencontainers/runtime-tools v0.9.1-0.20221014010322-58c91d646d86/go.
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
github.com/opencontainers/selinux v1.8.5/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
@ -2154,7 +2147,6 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -47,6 +47,7 @@ type SystemDfOptions struct {
// SystemDfReport describes the response for df information
type SystemDfReport struct {
ImagesSize int64
Images []*SystemDfImageReport
Containers []*SystemDfContainerReport
Volumes []*SystemDfVolumeReport

View File

@ -253,7 +253,7 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
dfImages = []*entities.SystemDfImageReport{}
)
imageStats, err := ic.Libpod.LibimageRuntime().DiskUsage(ctx)
imageStats, totalImageSize, err := ic.Libpod.LibimageRuntime().DiskUsage(ctx)
if err != nil {
return nil, err
}
@ -352,7 +352,9 @@ func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.System
}
dfVolumes = append(dfVolumes, &report)
}
return &entities.SystemDfReport{
ImagesSize: totalImageSize,
Images: dfImages,
Containers: dfContainers,
Volumes: dfVolumes,

View File

@ -8,7 +8,7 @@ t POST 'libpod/system/prune?volumes=true&all=true' params='' 200
## podman system df
t GET system/df 200 '{"LayersSize":0,"Images":[],"Containers":[],"Volumes":[],"BuildCache":[],"BuilderSize":0}'
t GET libpod/system/df 200 '{"Images":[],"Containers":[],"Volumes":[]}'
t GET libpod/system/df 200 '{"ImagesSize":0,"Images":[],"Containers":[],"Volumes":[]}'
# Create volume. We expect df to report this volume next invocation of system/df
t GET libpod/info 200

View File

@ -52,10 +52,39 @@ function teardown() {
is "${lines[10]}" "[0-9a-f]\{64\} *[01] * 0B" \
"system df -v, 'Volumes', second line"
# Clean up
# Make sure that the return image "raw" size is correct
run_podman image inspect $IMAGE --format "{{.Size}}"
expectedSize="$output"
run_podman system df --format "{{.RawSize}}"
is "${lines[0]}" "$expectedSize" "raw image size is correct"
# Clean up and check reclaimable image data
run_podman system df --format '{{.Reclaimable}}'
is "${lines[0]}" "0B (0%)" "cannot reclaim image data as it's still used by the containers"
run_podman exec c2 touch /stop
run_podman wait c2
# Create a second image by committing a container.
run_podman container commit -q c1
image="$output"
run_podman system df --format '{{.Reclaimable}}'
is "${lines[0]}" ".* (100%)" "100 percent of image data is reclaimable because $IMAGE has unique size of 0"
# Make sure the unique size is now really 0. We cannot use --format for
# that unfortunately but we can exploit the fact that $IMAGE is used by
# two containers.
run_podman system df -v
is "$output" ".*0B\\s\\+2.*"
run_podman rm c1 c2
run_podman system df --format '{{.Reclaimable}}'
is "${lines[0]}" ".* (100%)" "100 percent of image data is reclaimable because all containers are gone"
run_podman rmi $image
run_podman volume rm -a
}

View File

@ -28,26 +28,51 @@ type ImageDiskUsage struct {
// DiskUsage calculates the disk usage for each image in the local containers
// storage. Note that a single image may yield multiple usage reports, one for
// each repository tag.
func (r *Runtime) DiskUsage(ctx context.Context) ([]ImageDiskUsage, error) {
func (r *Runtime) DiskUsage(ctx context.Context) ([]ImageDiskUsage, int64, error) {
layerTree, err := r.layerTree()
if err != nil {
return nil, err
return nil, -1, err
}
images, err := r.ListImages(ctx, nil, nil)
if err != nil {
return nil, err
return nil, -1, err
}
var totalSize int64
visitedImages := make(map[string]bool)
visistedLayers := make(map[string]bool)
var allUsages []ImageDiskUsage
for _, image := range images {
usages, err := diskUsageForImage(ctx, image, layerTree)
if err != nil {
return nil, err
return nil, -1, err
}
allUsages = append(allUsages, usages...)
if _, ok := visitedImages[image.ID()]; ok {
// Do not count an image twice
continue
}
return allUsages, err
visitedImages[image.ID()] = true
size, err := image.Size()
if err != nil {
return nil, -1, err
}
for _, layer := range layerTree.layersOf(image) {
if _, ok := visistedLayers[layer.ID]; ok {
// Do not count a layer twice, so remove its
// size from the image size.
size -= layer.UncompressedSize
continue
}
visistedLayers[layer.ID] = true
}
totalSize += size
}
return allUsages, totalSize, err
}
// diskUsageForImage returns the disk-usage baseistics for the specified image.

View File

@ -73,6 +73,7 @@ func (r *Runtime) filterImages(ctx context.Context, images []*Image, options *Li
// compileImageFilters creates `filterFunc`s for the specified filters. The
// required format is `key=value` with the following supported keys:
//
// after, since, before, containers, dangling, id, label, readonly, reference, intermediate
func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOptions) (map[string][]filterFunc, error) {
logrus.Tracef("Parsing image filters %s", options.Filters)

View File

@ -775,6 +775,7 @@ func (i *Image) Unmount(force bool) error {
// Size computes the size of the image layers and associated data.
func (i *Image) Size() (int64, error) {
// TODO: cache the result to optimize performance of subsequent calls
return i.runtime.store.ImageSize(i.ID())
}

View File

@ -126,6 +126,17 @@ func (r *Runtime) layerTree() (*layerTree, error) {
return &tree, nil
}
// layersOf returns all storage layers of the specified image.
func (t *layerTree) layersOf(image *Image) []*storage.Layer {
var layers []*storage.Layer
node := t.node(image.TopLayer())
for node != nil {
layers = append(layers, node.layer)
node = node.parent
}
return layers
}
// children returns the child images of parent. Child images are images with
// either the same top layer as parent or parent being the true parent layer.
// Furthermore, the history of the parent and child images must match with the

View File

@ -69,9 +69,9 @@ func toPlatformString(os, arch, variant string) string {
// Checks whether the image matches the specified platform.
// Returns
// * 1) a matching error that can be used for logging (or returning) what does not match
// * 2) a bool indicating whether architecture, os or variant were set (some callers need that to decide whether they need to throw an error)
// * 3) a fatal error that occurred prior to check for matches (e.g., storage errors etc.)
// - 1) a matching error that can be used for logging (or returning) what does not match
// - 2) a bool indicating whether architecture, os or variant were set (some callers need that to decide whether they need to throw an error)
// - 3) a fatal error that occurred prior to check for matches (e.g., storage errors etc.)
func (i *Image) matchesPlatform(ctx context.Context, os, arch, variant string) (error, bool, error) {
if err := i.isCorrupted(""); err != nil {
return err, false, nil

View File

@ -7,7 +7,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
@ -329,7 +328,7 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ
cniPathName := ""
if writeToDisk {
cniPathName = filepath.Join(n.cniConfigDir, network.Name+".conflist")
err = ioutil.WriteFile(cniPathName, b, 0o644)
err = os.WriteFile(cniPathName, b, 0o644)
if err != nil {
return nil, "", err
}

View File

@ -7,7 +7,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -174,7 +173,7 @@ func (n *netavarkNetwork) loadNetworks() error {
n.networks = nil
n.modTime = modTime
files, err := ioutil.ReadDir(n.networkConfigDir)
files, err := os.ReadDir(n.networkConfigDir)
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}

View File

@ -6,7 +6,6 @@ package network
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
@ -42,6 +41,7 @@ const (
// 3. check containers, images and CNI networks and if there are some we have an existing install and should continue to use CNI
//
// revive does not like the name because the package is already called network
//
//nolint:revive
func NetworkBackend(store storage.Store, conf *config.Config, syslog bool) (types.NetworkBackend, types.ContainerNetwork, error) {
backend := types.NetworkBackend(conf.Network.NetworkBackend)
@ -100,7 +100,7 @@ func NetworkBackend(store storage.Store, conf *config.Config, syslog bool) (type
func defaultNetworkBackend(store storage.Store, conf *config.Config) (backend types.NetworkBackend, err error) {
// read defaultNetworkBackend file
file := filepath.Join(store.GraphRoot(), defaultNetworkBackendFileName)
b, err := ioutil.ReadFile(file)
b, err := os.ReadFile(file)
if err == nil {
val := string(b)
if val == string(types.Netavark) {

View File

@ -45,7 +45,6 @@ var (
// cleaned config has no defined nameservers left, adds default DNS entries
// 2. Given the caller provides the enable/disable state of IPv6, the filter
// code will remove all IPv6 nameservers if it is not enabled for containers
//
func filterResolvDNS(resolvConf []byte, ipv6Enabled bool, netnsEnabled bool) []byte {
// If we're using the host netns, we have nothing to do besides hash the file.
if !netnsEnabled {

View File

@ -226,6 +226,9 @@ type NetworkOptions struct {
// Networks contains all networks with the PerNetworkOptions.
// The map should contain at least one element.
Networks map[string]PerNetworkOptions `json:"networks"`
// List of custom DNS server for podman's DNS resolver.
// Priority order will be kept as defined by user in the configuration.
DNSServers []string `json:"dns_servers,omitempty"`
}
// PortMapping is one or more ports that will be mapped into the container.

View File

@ -8,7 +8,6 @@ import (
"context"
"errors"
"fmt"
"io/ioutil"
"math"
"os"
"path/filepath"
@ -143,7 +142,7 @@ func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool)
basePath := cgroupRoot + userSlice
controllersFile = fmt.Sprintf("%s/cgroup.controllers", basePath)
}
controllersFileBytes, err := ioutil.ReadFile(controllersFile)
controllersFileBytes, err := os.ReadFile(controllersFile)
if err != nil {
return nil, fmt.Errorf("failed while reading controllers for cgroup v2: %w", err)
}
@ -294,7 +293,7 @@ func (c *CgroupControl) initialize() (err error) {
}
func readFileAsUint64(path string) (uint64, error) {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
return 0, err
}
@ -310,7 +309,7 @@ func readFileAsUint64(path string) (uint64, error) {
}
func readFileByKeyAsUint64(path, key string) (uint64, error) {
content, err := ioutil.ReadFile(path)
content, err := os.ReadFile(path)
if err != nil {
return 0, err
}
@ -533,7 +532,7 @@ func (c *CgroupControl) AddPid(pid int) error {
if c.cgroup2 {
p := filepath.Join(cgroupRoot, c.path, "cgroup.procs")
if err := ioutil.WriteFile(p, pidString, 0o644); err != nil {
if err := os.WriteFile(p, pidString, 0o644); err != nil {
return fmt.Errorf("write %s: %w", p, err)
}
return nil
@ -556,7 +555,7 @@ func (c *CgroupControl) AddPid(pid int) error {
continue
}
p := filepath.Join(c.getCgroupv1Path(n), "tasks")
if err := ioutil.WriteFile(p, pidString, 0o644); err != nil {
if err := os.WriteFile(p, pidString, 0o644); err != nil {
return fmt.Errorf("write %s: %w", p, err)
}
}

View File

@ -8,7 +8,6 @@ import (
"context"
"errors"
"fmt"
"io/ioutil"
"math"
"os"
"path/filepath"
@ -96,7 +95,7 @@ func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool)
basePath := cgroupRoot + userSlice
controllersFile = fmt.Sprintf("%s/cgroup.controllers", basePath)
}
controllersFileBytes, err := ioutil.ReadFile(controllersFile)
controllersFileBytes, err := os.ReadFile(controllersFile)
if err != nil {
return nil, fmt.Errorf("failed while reading controllers for cgroup v2: %w", err)
}
@ -247,7 +246,7 @@ func (c *CgroupControl) initialize() (err error) {
}
func readFileAsUint64(path string) (uint64, error) {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
return 0, err
}
@ -263,7 +262,7 @@ func readFileAsUint64(path string) (uint64, error) {
}
func readFileByKeyAsUint64(path, key string) (uint64, error) {
content, err := ioutil.ReadFile(path)
content, err := os.ReadFile(path)
if err != nil {
return 0, err
}
@ -516,7 +515,7 @@ func (c *CgroupControl) AddPid(pid int) error {
continue
}
p := filepath.Join(c.getCgroupv1Path(n), "tasks")
if err := ioutil.WriteFile(p, pidString, 0o644); err != nil {
if err := os.WriteFile(p, pidString, 0o644); err != nil {
return fmt.Errorf("write %s: %w", p, err)
}
}

View File

@ -7,7 +7,6 @@ import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@ -99,12 +98,12 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) {
func rmDirRecursively(path string) error {
killProcesses := func(signal syscall.Signal) {
if signal == unix.SIGKILL {
if err := ioutil.WriteFile(filepath.Join(path, "cgroup.kill"), []byte("1"), 0o600); err == nil {
if err := os.WriteFile(filepath.Join(path, "cgroup.kill"), []byte("1"), 0o600); err == nil {
return
}
}
// kill all the processes that are still part of the cgroup
if procs, err := ioutil.ReadFile(filepath.Join(path, "cgroup.procs")); err == nil {
if procs, err := os.ReadFile(filepath.Join(path, "cgroup.procs")); err == nil {
for _, pidS := range strings.Split(string(procs), "\n") {
if pid, err := strconv.Atoi(pidS); err == nil {
_ = unix.Kill(pid, signal)
@ -116,7 +115,7 @@ func rmDirRecursively(path string) error {
if err := os.Remove(path); err == nil || errors.Is(err, os.ErrNotExist) {
return nil
}
entries, err := ioutil.ReadDir(path)
entries, err := os.ReadDir(path)
if err != nil {
return err
}

View File

@ -5,7 +5,7 @@ package cgroups
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
spec "github.com/opencontainers/runtime-spec/specs-go"
@ -31,7 +31,7 @@ func (c *pidHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error {
}
p := filepath.Join(PIDRoot, "pids.max")
return ioutil.WriteFile(p, []byte(fmt.Sprintf("%d\n", res.Pids.Limit)), 0o644)
return os.WriteFile(p, []byte(fmt.Sprintf("%d\n", res.Pids.Limit)), 0o644)
}
// Create the cgroup

View File

@ -53,18 +53,20 @@ func systemdCreate(path string, c *systemdDbus.Conn) error {
}
/*
systemdDestroyConn is copied from containerd/cgroups/systemd.go file, that
has the following license:
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
systemdDestroyConn is copied from containerd/cgroups/systemd.go file, that
has the following license:
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
func systemdDestroyConn(path string, c *systemdDbus.Conn) error {
name := filepath.Base(path)

View File

@ -108,22 +108,22 @@ func systemdCreate(resources *configs.Resources, path string, c *systemdDbus.Con
}
/*
systemdDestroyConn is copied from containerd/cgroups/systemd.go file, that
has the following license:
systemdDestroyConn is copied from containerd/cgroups/systemd.go file, that
has the following license:
Copyright The containerd Authors.
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
func systemdDestroyConn(path string, c *systemdDbus.Conn) error {
name := filepath.Base(path)

View File

@ -4,7 +4,6 @@ import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@ -24,7 +23,7 @@ func readAcct(ctr *CgroupControl, name string) (uint64, error) {
func readAcctList(ctr *CgroupControl, name string) ([]uint64, error) {
p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name)
data, err := ioutil.ReadFile(p)
data, err := os.ReadFile(p)
if err != nil {
return nil, err
}
@ -54,7 +53,7 @@ func GetSystemCPUUsage() (uint64, error) {
return readFileAsUint64(p)
}
files, err := ioutil.ReadDir(cgroupRoot)
files, err := os.ReadDir(cgroupRoot)
if err != nil {
return 0, err
}
@ -90,7 +89,7 @@ func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) {
if cgroupv2 {
parentPath = fmt.Sprintf("%s.effective", parentPath)
}
data, err := ioutil.ReadFile(parentPath)
data, err := os.ReadFile(parentPath)
if err != nil {
// if the file doesn't exist, it is likely that the cpuset controller
// is not enabled in the kernel.
@ -106,7 +105,7 @@ func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) {
if err != nil {
return nil, err
}
if err := ioutil.WriteFile(path, data, 0o644); err != nil {
if err := os.WriteFile(path, data, 0o644); err != nil {
return nil, fmt.Errorf("write %s: %w", path, err)
}
return data, nil
@ -126,7 +125,7 @@ func createCgroupv2Path(path string) (deferredError error) {
if !strings.HasPrefix(path, cgroupRoot+"/") {
return fmt.Errorf("invalid cgroup path %s", path)
}
content, err := ioutil.ReadFile(cgroupRoot + "/cgroup.controllers")
content, err := os.ReadFile(cgroupRoot + "/cgroup.controllers")
if err != nil {
return err
}
@ -154,7 +153,7 @@ func createCgroupv2Path(path string) (deferredError error) {
// We enable the controllers for all the path components except the last one. It is not allowed to add
// PIDs if there are already enabled controllers.
if i < len(elements[3:])-1 {
if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), res, 0o755); err != nil {
if err := os.WriteFile(filepath.Join(current, "cgroup.subtree_control"), res, 0o755); err != nil {
return err
}
}

View File

@ -579,6 +579,7 @@ type SecretConfig struct {
// ConfigMapConfig represents the "configmap" TOML config table
//
// revive does not like the name because the package is already called config
//
//nolint:revive
type ConfigMapConfig struct {
// Driver specifies the configmap driver to use.
@ -1037,6 +1038,7 @@ func (c *Config) Capabilities(user string, addCapabilities, dropCapabilities []s
// Device parses device mapping string to a src, dest & permissions string
// Valid values for device looklike:
//
// '/dev/sdc"
// '/dev/sdc:/dev/xvdc"
// '/dev/sdc:/dev/xvdc:rwm"

View File

@ -685,4 +685,3 @@ func useUserConfigLocations() bool {
// GetRootlessUID == -1 on Windows, so exclude negative range
return unshare.GetRootlessUID() > 0
}

View File

@ -2,7 +2,6 @@ package config
import (
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
@ -37,7 +36,7 @@ func getDefaultProcessLimits() []string {
rlim := unix.Rlimit{Cur: oldMaxSize, Max: oldMaxSize}
oldrlim := rlim
// Attempt to set file limit and process limit to pid_max in OS
dat, err := ioutil.ReadFile("/proc/sys/kernel/pid_max")
dat, err := os.ReadFile("/proc/sys/kernel/pid_max")
if err == nil {
val := strings.TrimSuffix(string(dat), "\n")
max, err := strconv.ParseUint(val, 10, 64)

View File

@ -4,7 +4,7 @@
package config
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
@ -53,7 +53,7 @@ func defaultLogDriver() string {
func useSystemd() bool {
systemdOnce.Do(func() {
dat, err := ioutil.ReadFile("/proc/1/comm")
dat, err := os.ReadFile("/proc/1/comm")
if err == nil {
val := strings.TrimSuffix(string(dat), "\n")
usesSystemd = (val == "systemd")
@ -68,13 +68,13 @@ func useJournald() bool {
return
}
for _, root := range []string{"/run/log/journal", "/var/log/journal"} {
dirs, err := ioutil.ReadDir(root)
dirs, err := os.ReadDir(root)
if err != nil {
continue
}
for _, d := range dirs {
if d.IsDir() {
if _, err := ioutil.ReadDir(filepath.Join(root, d.Name())); err == nil {
if _, err := os.ReadDir(filepath.Join(root, d.Name())); err == nil {
usesJournald = true
return
}

View File

@ -3,14 +3,14 @@ package download
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
)
// FromURL downloads the specified source to a file in tmpdir (OS defaults if
// empty).
func FromURL(tmpdir, source string) (string, error) {
tmp, err := ioutil.TempFile(tmpdir, "")
tmp, err := os.CreateTemp(tmpdir, "")
if err != nil {
return "", fmt.Errorf("creating temporary download file: %w", err)
}

View File

@ -38,6 +38,7 @@ func ComputeUntilTimestamp(filterValues []string) (time.Time, error) {
// background.
//
// revive does not like the name because the package is already called filters
//
//nolint:revive
func FiltersFromRequest(r *http.Request) ([]string, error) {
var (

View File

@ -5,7 +5,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -31,7 +30,7 @@ func Read(path string, extensionStages []string) (*current.Hook, error) {
if !strings.HasSuffix(path, ".json") {
return nil, ErrNoJSONSuffix
}
content, err := ioutil.ReadFile(path)
content, err := os.ReadFile(path)
if err != nil {
return nil, err
}
@ -64,7 +63,7 @@ func read(content []byte) (hook *current.Hook, err error) {
// clobbering any previous entries with the same filenames.
func ReadDir(path string, extensionStages []string, hooks map[string]*current.Hook) error {
logrus.Debugf("reading hooks from %s", path)
files, err := ioutil.ReadDir(path)
files, err := os.ReadDir(path)
if err != nil {
return err
}

View File

@ -10,6 +10,7 @@ import (
)
// TODO: change name to MachineMarker since package is already called machine
//
//nolint:revive
type MachineMarker struct {
Enabled bool
@ -57,6 +58,7 @@ func IsPodmanMachine() bool {
}
// TODO: change name to HostType since package is already called machine
//
//nolint:revive
func MachineHostType() string {
return GetMachineMarker().Type

View File

@ -103,6 +103,7 @@ func ValidateVolumeOpts(options []string) ([]string, error) {
// Device parses device mapping string to a src, dest & permissions string
// Valid values for device looklike:
//
// '/dev/sdc"
// '/dev/sdc:/dev/xvdc"
// '/dev/sdc:/dev/xvdc:rwm"

View File

@ -33,13 +33,13 @@ import (
//
// Splitting rules
//
// 1) If string is not valid UTF-8, return it without splitting as
// 1. If string is not valid UTF-8, return it without splitting as
// single item array.
// 2) Assign all unicode characters into one of 4 sets: lower case
// 2. Assign all unicode characters into one of 4 sets: lower case
// letters, upper case letters, numbers, and all other characters.
// 3) Iterate through characters of string, introducing splits
// 3. Iterate through characters of string, introducing splits
// between adjacent characters that belong to different sets.
// 4) Iterate through array of split strings, and if a given string
// 4. Iterate through array of split strings, and if a given string
// is upper case:
// if subsequent string is lower case:
// move last character of upper case string to beginning of

View File

@ -4,6 +4,7 @@ Package report provides helper structs/methods/funcs for formatting output
To format output for an array of structs:
ExamplePodman:
headers := report.Headers(struct {
ID string
}{}, nil)
@ -24,6 +25,7 @@ ExamplePodman:
// fa85da03b40141899f3af3de6d27852b
ExampleUser:
headers := report.Headers(struct {
CID string
}{}, map[string]string{"CID":"ID"})
@ -67,7 +69,6 @@ The following template functions are added to the template when parsed:
report.Funcs() may be used to add additional template functions.
Adding an existing function will replace that function for the life of that template.
Note: Your code should not ignore errors
*/
package report

View File

@ -88,6 +88,7 @@ func truncateWithLength(source string, length int) string {
// Array of map is returned to support range templates
// Note: unexported fields can be supported by adding field to overrides
// Note: It is left to the developer to write out said headers
//
// Podman commands use the general rules of:
// 1) unchanged --format includes headers
// 2) --format '{{.ID}" # no headers

View File

@ -5,6 +5,7 @@ import "regexp"
var jsonRegex = regexp.MustCompile(`^\s*(json|{{\s*json\s*(\.)?\s*}})\s*$`)
// JSONFormat test CLI --format string to be a JSON request
//
// if report.IsJSON(cmd.Flag("format").Value.String()) {
// ... process JSON and output
// }

View File

@ -4,7 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"io"
"os"
"path/filepath"
"sort"
@ -96,7 +96,7 @@ func (d *Driver) Store(id string, data []byte) error {
if err != nil {
return err
}
err = ioutil.WriteFile(d.secretsDataFilePath, marshalled, 0o600)
err = os.WriteFile(d.secretsDataFilePath, marshalled, 0o600)
if err != nil {
return err
}
@ -120,7 +120,7 @@ func (d *Driver) Delete(id string) error {
if err != nil {
return err
}
err = ioutil.WriteFile(d.secretsDataFilePath, marshalled, 0o600)
err = os.WriteFile(d.secretsDataFilePath, marshalled, 0o600)
if err != nil {
return err
}
@ -145,7 +145,7 @@ func (d *Driver) getAllData() (map[string][]byte, error) {
}
defer file.Close()
byteValue, err := ioutil.ReadAll(file)
byteValue, err := io.ReadAll(file)
if err != nil {
return nil, err
}

View File

@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -60,7 +59,7 @@ func defaultDriverConfig() *driverConfig {
continue
}
cfg.Root = path
bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
bs, err := os.ReadFile(filepath.Join(path, ".gpg-id"))
if err != nil {
continue
}
@ -76,7 +75,7 @@ func (cfg *driverConfig) findGpgID() {
path := cfg.Root
for len(path) > 1 {
if _, err := os.Stat(filepath.Join(path, ".gpg-id")); err == nil {
bs, err := ioutil.ReadFile(filepath.Join(path, ".gpg-id"))
bs, err := os.ReadFile(filepath.Join(path, ".gpg-id"))
if err != nil {
continue
}
@ -106,7 +105,7 @@ func NewDriver(opts map[string]string) (*Driver, error) {
// List returns all secret IDs
func (d *Driver) List() (secrets []string, err error) {
files, err := ioutil.ReadDir(d.Root)
files, err := os.ReadDir(d.Root)
if err != nil {
return nil, fmt.Errorf("failed to read secret directory: %w", err)
}
@ -168,7 +167,7 @@ func (d *Driver) gpg(ctx context.Context, in io.Reader, out io.Writer, args ...s
cmd.Env = os.Environ()
cmd.Stdin = in
cmd.Stdout = out
cmd.Stderr = ioutil.Discard
cmd.Stderr = io.Discard
return cmd.Run()
}

View File

@ -56,6 +56,7 @@ var secretNameRegexp = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]*$`)
// SecretsManager holds information on handling secrets
//
// revive does not like the name because the package is already called secrets
//
//nolint:revive
type SecretsManager struct {
// secretsPath is the path to the db file where secrets are stored
@ -90,6 +91,7 @@ type Secret struct {
// Currently only the unencrypted filedriver is implemented.
//
// revive does not like the name because the package is already called secrets
//
//nolint:revive
type SecretsDriver interface {
// List lists all secret ids in the secrets data store

View File

@ -4,7 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"io"
"os"
"strings"
"time"
@ -51,7 +51,7 @@ func (s *SecretsManager) loadDB() error {
return err
}
byteValue, err := ioutil.ReadAll(file)
byteValue, err := io.ReadAll(file)
if err != nil {
return err
}
@ -176,7 +176,7 @@ func (s *SecretsManager) store(entry *Secret) error {
if err != nil {
return err
}
err = ioutil.WriteFile(s.secretsDBPath, marshalled, 0o600)
err = os.WriteFile(s.secretsDBPath, marshalled, 0o600)
if err != nil {
return err
}
@ -202,7 +202,7 @@ func (s *SecretsManager) delete(nameOrID string) error {
if err != nil {
return err
}
err = ioutil.WriteFile(s.secretsDBPath, marshalled, 0o600)
err = os.WriteFile(s.secretsDBPath, marshalled, 0o600)
if err != nil {
return err
}

View File

@ -3,7 +3,6 @@ package ssh
import (
"fmt"
"io"
"io/ioutil"
"net"
"net/url"
"os"
@ -106,7 +105,7 @@ func ReadPassword(prompt string) (pw []byte, err error) {
}
func PublicKey(path string, passphrase []byte) (ssh.Signer, error) {
key, err := ioutil.ReadFile(path)
key, err := os.ReadFile(path)
if err != nil {
return nil, err
}

View File

@ -4,7 +4,6 @@ import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -42,7 +41,7 @@ func (s subscriptionData) saveTo(dir string) error {
if err := os.MkdirAll(filepath.Dir(path), s.dirMode); err != nil {
return err
}
return ioutil.WriteFile(path, s.data, s.mode)
return os.WriteFile(path, s.data, s.mode)
}
func readAll(root, prefix string, parentMode os.FileMode) ([]subscriptionData, error) {
@ -50,7 +49,7 @@ func readAll(root, prefix string, parentMode os.FileMode) ([]subscriptionData, e
data := []subscriptionData{}
files, err := ioutil.ReadDir(path)
files, err := os.ReadDir(path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return data, nil
@ -90,7 +89,7 @@ func readFileOrDir(root, name string, parentMode os.FileMode) ([]subscriptionDat
}
return dirData, nil
}
bytes, err := ioutil.ReadFile(path)
bytes, err := os.ReadFile(path)
if err != nil {
return nil, err
}
@ -153,7 +152,9 @@ func getMountsMap(path string) (string, string, error) { //nolint
// containerRunDir: Private data for storing subscriptions on the host mounted in container.
// mountFile: Additional mount points required for the container.
// mountPoint: Container image mountpoint, or the directory from the hosts perspective that
//
// corresponds to `/` in the container.
//
// uid: to assign to content created for subscriptions
// gid: to assign to content created for subscriptions
// rootless: indicates whether container is running in rootless mode
@ -268,7 +269,7 @@ func addSubscriptionsFromMountsFile(filePath, mountLabel, containerRunDir string
if err := os.MkdirAll(filepath.Dir(ctrDirOrFileOnHost), s.dirMode); err != nil {
return nil, err
}
if err := ioutil.WriteFile(ctrDirOrFileOnHost, s.data, s.mode); err != nil {
if err := os.WriteFile(ctrDirOrFileOnHost, s.data, s.mode); err != nil {
return nil, fmt.Errorf("saving data to container filesystem: %w", err)
}
}

View File

@ -3,7 +3,6 @@ package sysinfo
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
@ -210,12 +209,12 @@ func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetI
return cgroupCpusetInfo{}
}
cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus"))
cpus, err := os.ReadFile(path.Join(mountPoint, "cpuset.cpus"))
if err != nil {
return cgroupCpusetInfo{}
}
mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems"))
mems, err := os.ReadFile(path.Join(mountPoint, "cpuset.mems"))
if err != nil {
return cgroupCpusetInfo{}
}
@ -255,7 +254,7 @@ func cgroupEnabled(mountPoint, name string) bool {
}
func readProcBool(file string) bool {
val, err := ioutil.ReadFile(file)
val, err := os.ReadFile(file)
if err != nil {
return false
}

View File

@ -103,8 +103,10 @@ func GetTimestamp(value string, reference time.Time) (string, error) {
// if the incoming nanosecond portion is longer or shorter than 9 digits it is
// converted to nanoseconds. The expectation is that the seconds and
// seconds will be used to create a time variable. For example:
//
// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0)
// if err == nil since := time.Unix(seconds, nanoseconds)
//
// returns seconds as def(aultSeconds) if value == ""
func ParseTimestamps(value string, def int64) (secs, nanoSecs int64, err error) {
if value == "" {

7
vendor/modules.txt vendored
View File

@ -75,7 +75,7 @@ github.com/containerd/containerd/log
github.com/containerd/containerd/pkg/userns
github.com/containerd/containerd/platforms
github.com/containerd/containerd/sys
# github.com/containerd/stargz-snapshotter/estargz v0.12.0
# github.com/containerd/stargz-snapshotter/estargz v0.12.1
## explicit; go 1.16
github.com/containerd/stargz-snapshotter/estargz
github.com/containerd/stargz-snapshotter/estargz/errorutil
@ -117,7 +117,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
# github.com/containers/common v0.50.2-0.20221014181637-a6a9c521b6a5
# github.com/containers/common v0.50.2-0.20221018104440-95c452ec992c
## explicit; go 1.17
github.com/containers/common/libimage
github.com/containers/common/libimage/define
@ -263,7 +263,7 @@ github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/host
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
# github.com/containers/storage v1.43.1-0.20221014174544-ebf857fda6f3
# github.com/containers/storage v1.43.1-0.20221018232308-33c396d1aacf => github.com/containers/storage v1.43.1-0.20221014174544-ebf857fda6f3
## explicit; go 1.16
github.com/containers/storage
github.com/containers/storage/drivers
@ -971,3 +971,4 @@ gopkg.in/yaml.v3
## explicit; go 1.12
sigs.k8s.io/yaml
# github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc
# github.com/containers/storage => github.com/containers/storage v1.43.1-0.20221014174544-ebf857fda6f3