Avoid unnecessary manually-coded loops

Use the "slices", "maps" standard library packages, or other
readily-available features.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2024-09-04 22:19:26 +02:00
parent ee94e88cdd
commit 35b3e0f41b
15 changed files with 81 additions and 269 deletions

View File

@ -770,12 +770,9 @@ func (s *store) Repair(report CheckReport, options *RepairOptions) []error {
return d return d
} }
isUnaccounted := func(errs []error) bool { isUnaccounted := func(errs []error) bool {
for _, err := range errs { return slices.ContainsFunc(errs, func(err error) bool {
if errors.Is(err, ErrLayerUnaccounted) { return errors.Is(err, ErrLayerUnaccounted)
return true })
}
}
return false
} }
sort.Slice(layersToDelete, func(i, j int) bool { sort.Slice(layersToDelete, func(i, j int) bool {
// we've not heard of either of them, so remove them in the order the driver suggested // we've not heard of either of them, so remove them in the order the driver suggested

View File

@ -3,6 +3,7 @@ package storage
import ( import (
"errors" "errors"
"fmt" "fmt"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"slices" "slices"
@ -163,17 +164,17 @@ type containerStore struct {
func copyContainer(c *Container) *Container { func copyContainer(c *Container) *Container {
return &Container{ return &Container{
ID: c.ID, ID: c.ID,
Names: copyStringSlice(c.Names), Names: slices.Clone(c.Names),
ImageID: c.ImageID, ImageID: c.ImageID,
LayerID: c.LayerID, LayerID: c.LayerID,
Metadata: c.Metadata, Metadata: c.Metadata,
BigDataNames: copyStringSlice(c.BigDataNames), BigDataNames: slices.Clone(c.BigDataNames),
BigDataSizes: copyStringInt64Map(c.BigDataSizes), BigDataSizes: maps.Clone(c.BigDataSizes),
BigDataDigests: copyStringDigestMap(c.BigDataDigests), BigDataDigests: maps.Clone(c.BigDataDigests),
Created: c.Created, Created: c.Created,
UIDMap: copyIDMap(c.UIDMap), UIDMap: copyIDMap(c.UIDMap),
GIDMap: copyIDMap(c.GIDMap), GIDMap: copyIDMap(c.GIDMap),
Flags: copyStringInterfaceMap(c.Flags), Flags: maps.Clone(c.Flags),
volatileStore: c.volatileStore, volatileStore: c.volatileStore,
} }
} }
@ -937,14 +938,7 @@ func (r *containerStore) SetBigData(id, key string, data []byte) error {
if !sizeOk || oldSize != c.BigDataSizes[key] || !digestOk || oldDigest != newDigest { if !sizeOk || oldSize != c.BigDataSizes[key] || !digestOk || oldDigest != newDigest {
save = true save = true
} }
addName := true if !slices.Contains(c.BigDataNames, key) {
for _, name := range c.BigDataNames {
if name == key {
addName = false
break
}
}
if addName {
c.BigDataNames = append(c.BigDataNames, key) c.BigDataNames = append(c.BigDataNames, key)
save = true save = true
} }

View File

@ -205,17 +205,13 @@ func DriverTestCreateFromTemplate(t testing.TB, drivername string, driverOptions
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err = checkChanges(noChanges, changes); err != nil { require.ElementsMatch(t, noChanges, changes)
t.Fatal(err)
}
changes, err = driver.Changes("ROFromTemplate", nil, "Snap3", nil, "") changes, err = driver.Changes("ROFromTemplate", nil, "Snap3", nil, "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err = checkChanges(noChanges, changes); err != nil { require.ElementsMatch(t, noChanges, changes)
t.Fatal(err)
}
if err := checkFile(driver, "FromTemplate", "testfile.txt", content); err != nil { if err := checkFile(driver, "FromTemplate", "testfile.txt", content); err != nil {
t.Fatal(err) t.Fatal(err)
@ -236,25 +232,19 @@ func DriverTestCreateFromTemplate(t testing.TB, drivername string, driverOptions
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err = checkChanges(expectedChanges, changes); err != nil { require.ElementsMatch(t, expectedChanges, changes)
t.Fatal(err)
}
changes, err = driver.Changes("FromTemplate", nil, "Base3", nil, "") changes, err = driver.Changes("FromTemplate", nil, "Base3", nil, "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err = checkChanges(expectedChanges, changes); err != nil { require.ElementsMatch(t, expectedChanges, changes)
t.Fatal(err)
}
changes, err = driver.Changes("ROFromTemplate", nil, "Base3", nil, "") changes, err = driver.Changes("ROFromTemplate", nil, "Base3", nil, "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err = checkChanges(expectedChanges, changes); err != nil { require.ElementsMatch(t, expectedChanges, changes)
t.Fatal(err)
}
verifyBase(t, driver, "Base3", defaultPerms) verifyBase(t, driver, "Base3", defaultPerms)
} }
@ -417,10 +407,7 @@ func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
require.ElementsMatch(t, expectedChanges, changes)
if err = checkChanges(expectedChanges, changes); err != nil {
t.Fatal(err)
}
} }
func writeRandomFile(path string, size uint64) error { func writeRandomFile(path string, size uint64) error {
@ -513,10 +500,7 @@ func DriverTestEcho(t testing.TB, drivername string, driverOptions ...string) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
require.ElementsMatch(t, expectedChanges, changes)
if err = checkChanges(expectedChanges, changes); err != nil {
t.Fatal(err)
}
if err := driver.Create(second, base, nil); err != nil { if err := driver.Create(second, base, nil); err != nil {
t.Fatal(err) t.Fatal(err)
@ -540,10 +524,7 @@ func DriverTestEcho(t testing.TB, drivername string, driverOptions ...string) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
require.ElementsMatch(t, expectedChanges, changes)
if err = checkChanges(expectedChanges, changes); err != nil {
t.Fatal(err)
}
if err = driver.Create(third, second, nil); err != nil { if err = driver.Create(third, second, nil); err != nil {
t.Fatal(err) t.Fatal(err)
@ -573,10 +554,7 @@ func DriverTestEcho(t testing.TB, drivername string, driverOptions ...string) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
require.ElementsMatch(t, expectedChanges, changes)
if err = checkChanges(expectedChanges, changes); err != nil {
t.Fatal(err)
}
err = driver.Put(third) err = driver.Put(third)
if err != nil { if err != nil {

View File

@ -12,7 +12,6 @@ import (
"math/rand" "math/rand"
"os" "os"
"path" "path"
"sort"
"testing" "testing"
graphdriver "github.com/containers/storage/drivers" graphdriver "github.com/containers/storage/drivers"
@ -270,33 +269,6 @@ func checkManyFiles(drv graphdriver.Driver, layer string, count int, seed int64)
return nil return nil
} }
type changeList []archive.Change
func (c changeList) Less(i, j int) bool {
if c[i].Path == c[j].Path {
return c[i].Kind < c[j].Kind
}
return c[i].Path < c[j].Path
}
func (c changeList) Len() int { return len(c) }
func (c changeList) Swap(i, j int) { c[j], c[i] = c[i], c[j] }
func checkChanges(expected, actual []archive.Change) error {
if len(expected) != len(actual) {
return fmt.Errorf("unexpected number of changes, expected %d, got %d", len(expected), len(actual))
}
sort.Sort(changeList(expected))
sort.Sort(changeList(actual))
for i := range expected {
if expected[i] != actual[i] {
return fmt.Errorf("unexpected change, expecting %v, got %v", expected[i], actual[i])
}
}
return nil
}
func addLayerFiles(drv graphdriver.Driver, layer, parent string, i int) error { func addLayerFiles(drv graphdriver.Driver, layer, parent string, i int) error {
root, err := drv.Get(layer, graphdriver.MountOpts{}) root, err := drv.Get(layer, graphdriver.MountOpts{})
if err != nil { if err != nil {

View File

@ -159,21 +159,7 @@ func init() {
} }
func hasMetacopyOption(opts []string) bool { func hasMetacopyOption(opts []string) bool {
for _, s := range opts { return slices.Contains(opts, "metacopy=on")
if s == "metacopy=on" {
return true
}
}
return false
}
func hasVolatileOption(opts []string) bool {
for _, s := range opts {
if s == "volatile" {
return true
}
}
return false
} }
func getMountProgramFlagFile(path string) string { func getMountProgramFlagFile(path string) string {
@ -1523,11 +1509,8 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
}) })
} }
for _, o := range optsList { if slices.Contains(optsList, "ro") {
if o == "ro" { readWrite = false
readWrite = false
break
}
} }
lowers, err := os.ReadFile(path.Join(dir, lowerFile)) lowers, err := os.ReadFile(path.Join(dir, lowerFile))
@ -1726,7 +1709,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
optsList = append(optsList, "userxattr") optsList = append(optsList, "userxattr")
} }
if options.Volatile && !hasVolatileOption(optsList) { if options.Volatile && !slices.Contains(optsList, "volatile") {
supported, err := d.getSupportsVolatile() supported, err := d.getSupportsVolatile()
if err != nil { if err != nil {
return "", err return "", err

View File

@ -2,6 +2,7 @@ package storage
import ( import (
"fmt" "fmt"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"slices" "slices"
@ -182,18 +183,18 @@ func copyImage(i *Image) *Image {
return &Image{ return &Image{
ID: i.ID, ID: i.ID,
Digest: i.Digest, Digest: i.Digest,
Digests: copyDigestSlice(i.Digests), Digests: slices.Clone(i.Digests),
Names: copyStringSlice(i.Names), Names: slices.Clone(i.Names),
NamesHistory: copyStringSlice(i.NamesHistory), NamesHistory: slices.Clone(i.NamesHistory),
TopLayer: i.TopLayer, TopLayer: i.TopLayer,
MappedTopLayers: copyStringSlice(i.MappedTopLayers), MappedTopLayers: slices.Clone(i.MappedTopLayers),
Metadata: i.Metadata, Metadata: i.Metadata,
BigDataNames: copyStringSlice(i.BigDataNames), BigDataNames: slices.Clone(i.BigDataNames),
BigDataSizes: copyStringInt64Map(i.BigDataSizes), BigDataSizes: maps.Clone(i.BigDataSizes),
BigDataDigests: copyStringDigestMap(i.BigDataDigests), BigDataDigests: maps.Clone(i.BigDataDigests),
Created: i.Created, Created: i.Created,
ReadOnly: i.ReadOnly, ReadOnly: i.ReadOnly,
Flags: copyStringInterfaceMap(i.Flags), Flags: maps.Clone(i.Flags),
} }
} }
@ -872,7 +873,9 @@ func (r *imageStore) Delete(id string) error {
delete(r.byname, name) delete(r.byname, name)
} }
for _, digest := range image.Digests { for _, digest := range image.Digests {
prunedList := imageSliceWithoutValue(r.bydigest[digest], image) prunedList := slices.DeleteFunc(r.bydigest[digest], func(i *Image) bool {
return i == image
})
if len(prunedList) == 0 { if len(prunedList) == 0 {
delete(r.bydigest, digest) delete(r.bydigest, digest)
} else { } else {
@ -967,17 +970,6 @@ func (r *imageStore) BigDataNames(id string) ([]string, error) {
return copyStringSlice(image.BigDataNames), nil return copyStringSlice(image.BigDataNames), nil
} }
func imageSliceWithoutValue(slice []*Image, value *Image) []*Image {
modified := make([]*Image, 0, len(slice))
for _, v := range slice {
if v == value {
continue
}
modified = append(modified, v)
}
return modified
}
// Requires startWriting. // Requires startWriting.
func (r *imageStore) SetBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error { func (r *imageStore) SetBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error {
if !r.lockfile.IsReadWrite() { if !r.lockfile.IsReadWrite() {
@ -1027,21 +1019,16 @@ func (r *imageStore) setBigData(image *Image, key string, data []byte, newDigest
if !sizeOk || oldSize != image.BigDataSizes[key] || !digestOk || oldDigest != newDigest { if !sizeOk || oldSize != image.BigDataSizes[key] || !digestOk || oldDigest != newDigest {
save = true save = true
} }
addName := true if !slices.Contains(image.BigDataNames, key) {
for _, name := range image.BigDataNames {
if name == key {
addName = false
break
}
}
if addName {
image.BigDataNames = append(image.BigDataNames, key) image.BigDataNames = append(image.BigDataNames, key)
save = true save = true
} }
for _, oldDigest := range image.Digests { for _, oldDigest := range image.Digests {
// remove the image from the list of images in the digest-based index // remove the image from the list of images in the digest-based index
if list, ok := r.bydigest[oldDigest]; ok { if list, ok := r.bydigest[oldDigest]; ok {
prunedList := imageSliceWithoutValue(list, image) prunedList := slices.DeleteFunc(list, func(i *Image) bool {
return i == image
})
if len(prunedList) == 0 { if len(prunedList) == 0 {
delete(r.bydigest, oldDigest) delete(r.bydigest, oldDigest)
} else { } else {
@ -1056,9 +1043,7 @@ func (r *imageStore) setBigData(image *Image, key string, data []byte, newDigest
// add the image to the list of images in the digest-based index which // add the image to the list of images in the digest-based index which
// corresponds to the new digest for this item, unless it's already there // corresponds to the new digest for this item, unless it's already there
list := r.bydigest[newDigest] list := r.bydigest[newDigest]
if len(list) == len(imageSliceWithoutValue(list, image)) { if !slices.Contains(list, image) {
// the list isn't shortened by trying to prune this image from it,
// so it's not in there yet
r.bydigest[newDigest] = append(list, image) r.bydigest[newDigest] = append(list, image)
} }
} }

View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"maps"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -436,7 +437,7 @@ func layerLocation(l *Layer) layerLocations {
func copyLayer(l *Layer) *Layer { func copyLayer(l *Layer) *Layer {
return &Layer{ return &Layer{
ID: l.ID, ID: l.ID,
Names: copyStringSlice(l.Names), Names: slices.Clone(l.Names),
Parent: l.Parent, Parent: l.Parent,
Metadata: l.Metadata, Metadata: l.Metadata,
MountLabel: l.MountLabel, MountLabel: l.MountLabel,
@ -451,8 +452,8 @@ func copyLayer(l *Layer) *Layer {
CompressionType: l.CompressionType, CompressionType: l.CompressionType,
ReadOnly: l.ReadOnly, ReadOnly: l.ReadOnly,
volatileStore: l.volatileStore, volatileStore: l.volatileStore,
BigDataNames: copyStringSlice(l.BigDataNames), BigDataNames: slices.Clone(l.BigDataNames),
Flags: copyStringInterfaceMap(l.Flags), Flags: maps.Clone(l.Flags),
UIDMap: copyIDMap(l.UIDMap), UIDMap: copyIDMap(l.UIDMap),
GIDMap: copyIDMap(l.GIDMap), GIDMap: copyIDMap(l.GIDMap),
UIDs: copyUint32Slice(l.UIDs), UIDs: copyUint32Slice(l.UIDs),
@ -1565,19 +1566,9 @@ func (r *layerStore) Mount(id string, options drivers.MountOpts) (string, error)
// - r.layers[].MountPoint (directly and via loadMounts / saveMounts) // - r.layers[].MountPoint (directly and via loadMounts / saveMounts)
// - r.bymount (via loadMounts / saveMounts) // - r.bymount (via loadMounts / saveMounts)
// check whether options include ro option
hasReadOnlyOpt := func(opts []string) bool {
for _, item := range opts {
if item == "ro" {
return true
}
}
return false
}
// You are not allowed to mount layers from readonly stores if they // You are not allowed to mount layers from readonly stores if they
// are not mounted read/only. // are not mounted read/only.
if !r.lockfile.IsReadWrite() && !hasReadOnlyOpt(options.Options) { if !r.lockfile.IsReadWrite() && !slices.Contains(options.Options, "ro") {
return "", fmt.Errorf("not allowed to update mount locations for layers at %q: %w", r.mountspath(), ErrStoreIsReadOnly) return "", fmt.Errorf("not allowed to update mount locations for layers at %q: %w", r.mountspath(), ErrStoreIsReadOnly)
} }
r.mountsLockfile.Lock() r.mountsLockfile.Lock()
@ -1837,14 +1828,7 @@ func (r *layerStore) setBigData(layer *Layer, key string, data io.Reader) error
return fmt.Errorf("closing bigdata file for the layer: %w", err) return fmt.Errorf("closing bigdata file for the layer: %w", err)
} }
addName := true if !slices.Contains(layer.BigDataNames, key) {
for _, name := range layer.BigDataNames {
if name == key {
addName = false
break
}
}
if addName {
layer.BigDataNames = append(layer.BigDataNames, key) layer.BigDataNames = append(layer.BigDataNames, key)
return r.saveFor(layer) return r.saveFor(layer)
} }
@ -1942,17 +1926,10 @@ func (r *layerStore) deleteInternal(id string) error {
r.layers = slices.DeleteFunc(r.layers, func(candidate *Layer) bool { r.layers = slices.DeleteFunc(r.layers, func(candidate *Layer) bool {
return candidate.ID == id return candidate.ID == id
}) })
if mountLabel != "" { if mountLabel != "" && !slices.ContainsFunc(r.layers, func(candidate *Layer) bool {
var found bool return candidate.MountLabel == mountLabel
for _, candidate := range r.layers { }) {
if candidate.MountLabel == mountLabel { selinux.ReleaseLabel(mountLabel)
found = true
break
}
}
if !found {
selinux.ReleaseLabel(mountLabel)
}
} }
return nil return nil
} }
@ -2528,9 +2505,7 @@ func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *driver
if layer.Flags == nil { if layer.Flags == nil {
layer.Flags = make(map[string]interface{}) layer.Flags = make(map[string]interface{})
} }
for k, v := range options.Flags { maps.Copy(layer.Flags, options.Flags)
layer.Flags[k] = v
}
} }
if err = r.saveFor(layer); err != nil { if err = r.saveFor(layer); err != nil {
return err return err

View File

@ -5,6 +5,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
@ -319,9 +320,7 @@ func (info *FileInfo) addChanges(oldInfo *FileInfo, changes *[]Change) {
// otherwise any previous delete/change is considered recursive // otherwise any previous delete/change is considered recursive
oldChildren := make(map[string]*FileInfo) oldChildren := make(map[string]*FileInfo)
if oldInfo != nil && info.isDir() { if oldInfo != nil && info.isDir() {
for k, v := range oldInfo.children { maps.Copy(oldChildren, oldInfo.children)
oldChildren[k] = v
}
} }
for name, newChild := range info.children { for name, newChild := range info.children {

View File

@ -6,6 +6,7 @@ import (
"io" "io"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -36,19 +37,7 @@ func TestGenerateEmptyFile(t *testing.T) {
actualFiles = append(actualFiles, []string{hdr.Name, content}) actualFiles = append(actualFiles, []string{hdr.Name, content})
i++ i++
} }
if len(actualFiles) != len(expectedFiles) { assert.Equal(t, expectedFiles, actualFiles)
t.Fatalf("Number of expected file %d, got %d.", len(expectedFiles), len(actualFiles))
}
for i := 0; i < len(expectedFiles); i++ {
actual := actualFiles[i]
expected := expectedFiles[i]
if actual[0] != expected[0] {
t.Fatalf("Expected name '%s', Actual name '%s'", expected[0], actual[0])
}
if actual[1] != expected[1] {
t.Fatalf("Expected content '%s', Actual content '%s'", expected[1], actual[1])
}
}
} }
func TestGenerateWithContent(t *testing.T) { func TestGenerateWithContent(t *testing.T) {
@ -78,17 +67,5 @@ func TestGenerateWithContent(t *testing.T) {
actualFiles = append(actualFiles, []string{hdr.Name, content}) actualFiles = append(actualFiles, []string{hdr.Name, content})
i++ i++
} }
if len(actualFiles) != len(expectedFiles) { assert.Equal(t, expectedFiles, actualFiles)
t.Fatalf("Number of expected file %d, got %d.", len(expectedFiles), len(actualFiles))
}
for i := 0; i < len(expectedFiles); i++ {
actual := actualFiles[i]
expected := expectedFiles[i]
if actual[0] != expected[0] {
t.Fatalf("Expected name '%s', Actual name '%s'", expected[0], actual[0])
}
if actual[1] != expected[1] {
t.Fatalf("Expected content '%s', Actual content '%s'", expected[1], actual[1])
}
}
} }

View File

@ -5,6 +5,7 @@ package idtools
import ( import (
"fmt" "fmt"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -192,9 +193,7 @@ func readTree(base, root string) (map[string]node, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
for path, nodeinfo := range subtree { maps.Copy(tree, subtree)
tree[path] = nodeinfo
}
} }
} }
return tree, nil return tree, nil

View File

@ -86,6 +86,7 @@ import (
"io" "io"
"os" "os"
"runtime" "runtime"
"slices"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -356,14 +357,7 @@ func sortFlags(flags map[string]*Flag) []*Flag {
continue continue
} }
found := false if !slices.Contains(list, fName) {
for _, name := range list {
if name == fName {
found = true
break
}
}
if !found {
list = append(list, fName) list = append(list, fName)
} }
} }

View File

@ -6,7 +6,10 @@ package mount
import ( import (
"os" "os"
"path" "path"
"slices"
"testing" "testing"
"github.com/stretchr/testify/require"
) )
func TestMountOptionsParsing(t *testing.T) { func TestMountOptionsParsing(t *testing.T) {
@ -151,14 +154,9 @@ func TestGetMounts(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
root := false if !slices.ContainsFunc(mounts, func(entry *Info) bool {
for _, entry := range mounts { return entry.Mountpoint == "/"
if entry.Mountpoint == "/" { }) {
root = true
}
}
if !root {
t.Fatal("/ should be mounted at least") t.Fatal("/ should be mounted at least")
} }
} }
@ -170,14 +168,7 @@ func TestMergeTmpfsOptions(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if len(expected) != len(merged) { require.Equal(t, expected, merged)
t.Fatalf("Expected %s got %s", expected, merged)
}
for index := range merged {
if merged[index] != expected[index] {
t.Fatalf("Expected %s for the %dth option, got %s", expected, index, merged)
}
}
options = []string{"noatime", "ro", "size=10k", "atime", "rw", "rprivate", "size=1024k", "slave", "size"} options = []string{"noatime", "ro", "size=10k", "atime", "rw", "rprivate", "size=1024k", "slave", "size"}
_, err = MergeTmpfsOptions(options) _, err = MergeTmpfsOptions(options)

View File

@ -2,6 +2,7 @@ package truncindex
import ( import (
"math/rand/v2" "math/rand/v2"
"slices"
"testing" "testing"
"time" "time"
@ -114,13 +115,9 @@ func assertIndexIterate(t *testing.T) {
index := NewTruncIndex(ids) index := NewTruncIndex(ids)
index.Iterate(func(targetId string) { index.Iterate(func(targetId string) {
for _, id := range ids { if !slices.Contains(ids, targetId) {
if targetId == id { t.Fatalf("An unknown ID '%s'", targetId)
return
}
} }
t.Fatalf("An unknown ID '%s'", targetId)
}) })
} }

View File

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
@ -940,9 +941,7 @@ func (s *store) GraphOptions() []string {
func (s *store) PullOptions() map[string]string { func (s *store) PullOptions() map[string]string {
cp := make(map[string]string, len(s.pullOptions)) cp := make(map[string]string, len(s.pullOptions))
for k, v := range s.pullOptions { maps.Copy(cp, s.pullOptions)
cp[k] = v
}
return cp return cp
} }
@ -1465,7 +1464,7 @@ func (s *store) putLayer(rlstore rwLayerStore, rlstores []roLayerStore, id, pare
if lOptions != nil { if lOptions != nil {
options = *lOptions options = *lOptions
options.BigData = copyLayerBigDataOptionSlice(lOptions.BigData) options.BigData = copyLayerBigDataOptionSlice(lOptions.BigData)
options.Flags = copyStringInterfaceMap(lOptions.Flags) options.Flags = maps.Clone(lOptions.Flags)
} }
if options.HostUIDMapping { if options.HostUIDMapping {
options.UIDMap = nil options.UIDMap = nil
@ -1606,7 +1605,7 @@ func (s *store) CreateImage(id string, names []string, layer, metadata string, i
CreationDate: i.Created, CreationDate: i.Created,
Digest: i.Digest, Digest: i.Digest,
Digests: copyDigestSlice(i.Digests), Digests: copyDigestSlice(i.Digests),
NamesHistory: copyStringSlice(i.NamesHistory), NamesHistory: slices.Clone(i.NamesHistory),
} }
for _, key := range i.BigDataNames { for _, key := range i.BigDataNames {
data, err := store.BigData(id, key) data, err := store.BigData(id, key)
@ -1637,18 +1636,16 @@ func (s *store) CreateImage(id string, names []string, layer, metadata string, i
if iOptions.Digest != "" { if iOptions.Digest != "" {
options.Digest = iOptions.Digest options.Digest = iOptions.Digest
} }
options.Digests = append(options.Digests, copyDigestSlice(iOptions.Digests)...) options.Digests = append(options.Digests, iOptions.Digests...)
if iOptions.Metadata != "" { if iOptions.Metadata != "" {
options.Metadata = iOptions.Metadata options.Metadata = iOptions.Metadata
} }
options.BigData = append(options.BigData, copyImageBigDataOptionSlice(iOptions.BigData)...) options.BigData = append(options.BigData, copyImageBigDataOptionSlice(iOptions.BigData)...)
options.NamesHistory = append(options.NamesHistory, copyStringSlice(iOptions.NamesHistory)...) options.NamesHistory = append(options.NamesHistory, iOptions.NamesHistory...)
if options.Flags == nil { if options.Flags == nil {
options.Flags = make(map[string]interface{}) options.Flags = make(map[string]interface{})
} }
for k, v := range iOptions.Flags { maps.Copy(options.Flags, iOptions.Flags)
options.Flags[k] = v
}
} }
if options.CreationDate.IsZero() { if options.CreationDate.IsZero() {
@ -1783,7 +1780,7 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
options.IDMappingOptions.UIDMap = copyIDMap(cOptions.IDMappingOptions.UIDMap) options.IDMappingOptions.UIDMap = copyIDMap(cOptions.IDMappingOptions.UIDMap)
options.IDMappingOptions.GIDMap = copyIDMap(cOptions.IDMappingOptions.GIDMap) options.IDMappingOptions.GIDMap = copyIDMap(cOptions.IDMappingOptions.GIDMap)
options.LabelOpts = copyStringSlice(cOptions.LabelOpts) options.LabelOpts = copyStringSlice(cOptions.LabelOpts)
options.Flags = copyStringInterfaceMap(cOptions.Flags) options.Flags = maps.Clone(cOptions.Flags)
options.MountOpts = copyStringSlice(cOptions.MountOpts) options.MountOpts = copyStringSlice(cOptions.MountOpts)
options.StorageOpt = copyStringStringMap(cOptions.StorageOpt) options.StorageOpt = copyStringStringMap(cOptions.StorageOpt)
options.BigData = copyContainerBigDataOptionSlice(cOptions.BigData) options.BigData = copyContainerBigDataOptionSlice(cOptions.BigData)
@ -3684,22 +3681,6 @@ func copyStringSlice(slice []string) []string {
return ret return ret
} }
func copyStringInt64Map(m map[string]int64) map[string]int64 {
ret := make(map[string]int64, len(m))
for k, v := range m {
ret[k] = v
}
return ret
}
func copyStringDigestMap(m map[string]digest.Digest) map[string]digest.Digest {
ret := make(map[string]digest.Digest, len(m))
for k, v := range m {
ret[k] = v
}
return ret
}
func copyStringStringMap(m map[string]string) map[string]string { func copyStringStringMap(m map[string]string) map[string]string {
ret := make(map[string]string, len(m)) ret := make(map[string]string, len(m))
for k, v := range m { for k, v := range m {
@ -3801,10 +3782,8 @@ func GetMountOptions(driver string, graphDriverOptions []string) ([]string, erro
return nil, err return nil, err
} }
key = strings.ToLower(key) key = strings.ToLower(key)
for _, m := range mountOpts { if slices.Contains(mountOpts, key) {
if m == key { return strings.Split(val, ","), nil
return strings.Split(val, ","), nil
}
} }
} }
return nil, nil return nil, nil

View File

@ -42,15 +42,7 @@ func applyNameOperation(oldNames []string, opParameters []string, op updateNameO
// remove given names from old names // remove given names from old names
result = make([]string, 0, len(oldNames)) result = make([]string, 0, len(oldNames))
for _, name := range oldNames { for _, name := range oldNames {
// only keep names in final result which do not intersect with input names if !slices.Contains(opParameters, name) {
// basically `result = oldNames - opParameters`
nameShouldBeRemoved := false
for _, opName := range opParameters {
if name == opName {
nameShouldBeRemoved = true
}
}
if !nameShouldBeRemoved {
result = append(result, name) result = append(result, name)
} }
} }