Bump github.com/containers/storage@d10d868
Update the vendored copy of github.com/containers/storage to revision d10d8680af74070b362637408a7fe28c4b1f1eff. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
parent
d6bf131c07
commit
7c551964c0
20 changed files with 925 additions and 441 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"memo": "e99fe9f7a283d8fb8e0ec8b05fa68d01a7dfa4c7c48b6e85a84986a079685711",
|
"memo": "5791d48b7e77e9f18a26535dfb184838f1d863f5d364fc9907cf16b6013e9846",
|
||||||
"projects": [
|
"projects": [
|
||||||
{
|
{
|
||||||
"name": "cloud.google.com/go",
|
"name": "cloud.google.com/go",
|
||||||
|
@ -117,13 +117,13 @@
|
||||||
{
|
{
|
||||||
"name": "github.com/containers/storage",
|
"name": "github.com/containers/storage",
|
||||||
"branch": "master",
|
"branch": "master",
|
||||||
"revision": "ff48947baaf205756dd67a00ac688d694a778ef6",
|
"revision": "d10d8680af74070b362637408a7fe28c4b1f1eff",
|
||||||
"packages": [
|
"packages": [
|
||||||
"drivers",
|
"drivers",
|
||||||
"drivers/aufs",
|
"drivers/aufs",
|
||||||
"drivers/btrfs",
|
"drivers/btrfs",
|
||||||
"drivers/devmapper",
|
"drivers/devmapper",
|
||||||
"drivers/overlay2",
|
"drivers/overlay",
|
||||||
"drivers/register",
|
"drivers/register",
|
||||||
"drivers/vfs",
|
"drivers/vfs",
|
||||||
"drivers/windows",
|
"drivers/windows",
|
||||||
|
@ -149,6 +149,7 @@
|
||||||
"pkg/reexec",
|
"pkg/reexec",
|
||||||
"pkg/stringid",
|
"pkg/stringid",
|
||||||
"pkg/system",
|
"pkg/system",
|
||||||
|
"pkg/truncindex",
|
||||||
"storage",
|
"storage",
|
||||||
"storageversion"
|
"storageversion"
|
||||||
]
|
]
|
||||||
|
|
23
vendor/github.com/containers/storage/cmd/oci-storage/container.go
generated
vendored
23
vendor/github.com/containers/storage/cmd/oci-storage/container.go
generated
vendored
|
@ -20,25 +20,10 @@ func container(flags *mflag.FlagSet, action string, m storage.Store, args []stri
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
containers, err := m.Containers()
|
matches := []*storage.Container{}
|
||||||
if err != nil {
|
for _, arg := range args {
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
if container, err := m.GetContainer(arg); err == nil {
|
||||||
return 1
|
matches = append(matches, container)
|
||||||
}
|
|
||||||
matches := []storage.Container{}
|
|
||||||
for _, container := range containers {
|
|
||||||
nextContainer:
|
|
||||||
for _, arg := range args {
|
|
||||||
if container.ID == arg {
|
|
||||||
matches = append(matches, container)
|
|
||||||
break nextContainer
|
|
||||||
}
|
|
||||||
for _, name := range container.Names {
|
|
||||||
if name == arg {
|
|
||||||
matches = append(matches, container)
|
|
||||||
break nextContainer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if jsonOutput {
|
if jsonOutput {
|
||||||
|
|
23
vendor/github.com/containers/storage/cmd/oci-storage/image.go
generated
vendored
23
vendor/github.com/containers/storage/cmd/oci-storage/image.go
generated
vendored
|
@ -15,25 +15,10 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func image(flags *mflag.FlagSet, action string, m storage.Store, args []string) int {
|
func image(flags *mflag.FlagSet, action string, m storage.Store, args []string) int {
|
||||||
images, err := m.Images()
|
matched := []*storage.Image{}
|
||||||
if err != nil {
|
for _, arg := range args {
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
if image, err := m.GetImage(arg); err == nil {
|
||||||
return 1
|
matched = append(matched, image)
|
||||||
}
|
|
||||||
matched := []storage.Image{}
|
|
||||||
for _, image := range images {
|
|
||||||
nextImage:
|
|
||||||
for _, arg := range args {
|
|
||||||
if image.ID == arg {
|
|
||||||
matched = append(matched, image)
|
|
||||||
break nextImage
|
|
||||||
}
|
|
||||||
for _, name := range image.Names {
|
|
||||||
if name == arg {
|
|
||||||
matched = append(matched, image)
|
|
||||||
break nextImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if jsonOutput {
|
if jsonOutput {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package overlay2
|
package overlay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
|
@ -1,6 +1,6 @@
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package overlay2
|
package overlay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
@ -61,10 +61,9 @@ var (
|
||||||
// that mounts do not fail due to length.
|
// that mounts do not fail due to length.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
driverName = "overlay2"
|
linkDir = "l"
|
||||||
linkDir = "l"
|
lowerFile = "lower"
|
||||||
lowerFile = "lower"
|
maxDepth = 128
|
||||||
maxDepth = 128
|
|
||||||
|
|
||||||
// idLength represents the number of random characters
|
// idLength represents the number of random characters
|
||||||
// which can be used to create the unique link identifer
|
// which can be used to create the unique link identifer
|
||||||
|
@ -78,6 +77,7 @@ const (
|
||||||
|
|
||||||
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
|
// Driver contains information about the home directory and the list of active mounts that are created using this driver.
|
||||||
type Driver struct {
|
type Driver struct {
|
||||||
|
name string
|
||||||
home string
|
home string
|
||||||
uidMaps []idtools.IDMap
|
uidMaps []idtools.IDMap
|
||||||
gidMaps []idtools.IDMap
|
gidMaps []idtools.IDMap
|
||||||
|
@ -87,13 +87,13 @@ type Driver struct {
|
||||||
var backingFs = "<unknown>"
|
var backingFs = "<unknown>"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
graphdriver.Register(driverName, Init)
|
graphdriver.Register("overlay", InitAsOverlay)
|
||||||
|
graphdriver.Register("overlay2", InitAsOverlay2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init returns the a native diff driver for overlay filesystem.
|
// InitWithName returns the a naive diff driver for the overlay filesystem,
|
||||||
// If overlay filesystem is not supported on the host, graphdriver.ErrNotSupported is returned as error.
|
// which returns the passed-in name when asked which driver it is.
|
||||||
// If a overlay filesystem is not supported over a existing filesystem then error graphdriver.ErrIncompatibleFS is returned.
|
func InitWithName(name, home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
|
||||||
func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
|
|
||||||
opts, err := parseOptions(options)
|
opts, err := parseOptions(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -112,7 +112,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||||
if !opts.overrideKernelCheck {
|
if !opts.overrideKernelCheck {
|
||||||
return nil, graphdriver.ErrNotSupported
|
return nil, graphdriver.ErrNotSupported
|
||||||
}
|
}
|
||||||
logrus.Warnf("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update")
|
logrus.Warnf("Using pre-4.0.0 kernel for overlay, mount failures may require kernel update")
|
||||||
}
|
}
|
||||||
|
|
||||||
fsMagic, err := graphdriver.GetFSMagic(home)
|
fsMagic, err := graphdriver.GetFSMagic(home)
|
||||||
|
@ -126,7 +126,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||||
// check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs
|
// check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs
|
||||||
switch fsMagic {
|
switch fsMagic {
|
||||||
case graphdriver.FsMagicBtrfs, graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs:
|
case graphdriver.FsMagicBtrfs, graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs:
|
||||||
logrus.Errorf("'overlay2' is not supported over %s", backingFs)
|
logrus.Errorf("'overlay' is not supported over %s", backingFs)
|
||||||
return nil, graphdriver.ErrIncompatibleFS
|
return nil, graphdriver.ErrIncompatibleFS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||||
}
|
}
|
||||||
|
|
||||||
d := &Driver{
|
d := &Driver{
|
||||||
|
name: name,
|
||||||
home: home,
|
home: home,
|
||||||
uidMaps: uidMaps,
|
uidMaps: uidMaps,
|
||||||
gidMaps: gidMaps,
|
gidMaps: gidMaps,
|
||||||
|
@ -153,6 +154,20 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitAsOverlay returns the a naive diff driver for overlay filesystem.
|
||||||
|
// If overlay filesystem is not supported on the host, graphdriver.ErrNotSupported is returned as error.
|
||||||
|
// If a overlay filesystem is not supported over a existing filesystem then error graphdriver.ErrIncompatibleFS is returned.
|
||||||
|
func InitAsOverlay(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
|
||||||
|
return InitWithName("overlay", home, options, uidMaps, gidMaps)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitAsOverlay2 returns the a naive diff driver for overlay filesystem.
|
||||||
|
// If overlay filesystem is not supported on the host, graphdriver.ErrNotSupported is returned as error.
|
||||||
|
// If a overlay filesystem is not supported over a existing filesystem then error graphdriver.ErrIncompatibleFS is returned.
|
||||||
|
func InitAsOverlay2(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
|
||||||
|
return InitWithName("overlay2", home, options, uidMaps, gidMaps)
|
||||||
|
}
|
||||||
|
|
||||||
type overlayOptions struct {
|
type overlayOptions struct {
|
||||||
overrideKernelCheck bool
|
overrideKernelCheck bool
|
||||||
}
|
}
|
||||||
|
@ -166,13 +181,13 @@ func parseOptions(options []string) (*overlayOptions, error) {
|
||||||
}
|
}
|
||||||
key = strings.ToLower(key)
|
key = strings.ToLower(key)
|
||||||
switch key {
|
switch key {
|
||||||
case "overlay2.override_kernel_check":
|
case "overlay.override_kernel_check", "overlay2.override_kernel_check":
|
||||||
o.overrideKernelCheck, err = strconv.ParseBool(val)
|
o.overrideKernelCheck, err = strconv.ParseBool(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("overlay2: Unknown option %s", key)
|
return nil, fmt.Errorf("overlay: Unknown option %s", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return o, nil
|
return o, nil
|
||||||
|
@ -200,7 +215,7 @@ func supportsOverlay() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) String() string {
|
func (d *Driver) String() string {
|
||||||
return driverName
|
return d.name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status returns current driver information in a two dimensional string array.
|
// Status returns current driver information in a two dimensional string array.
|
|
@ -1,6 +1,6 @@
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package overlay2
|
package overlay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
@ -13,6 +13,8 @@ import (
|
||||||
"github.com/containers/storage/pkg/reexec"
|
"github.com/containers/storage/pkg/reexec"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const driverName = "overlay"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Do not sure chroot to speed run time and allow archive
|
// Do not sure chroot to speed run time and allow archive
|
||||||
// errors or hangs to be debugged directly from the test process.
|
// errors or hangs to be debugged directly from the test process.
|
|
@ -1,3 +1,3 @@
|
||||||
// +build !linux
|
// +build !linux
|
||||||
|
|
||||||
package overlay2
|
package overlay
|
|
@ -1,6 +1,6 @@
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package overlay2
|
package overlay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
4
vendor/github.com/containers/storage/drivers/register/register_overlay.go
generated
vendored
4
vendor/github.com/containers/storage/drivers/register/register_overlay.go
generated
vendored
|
@ -3,6 +3,6 @@
|
||||||
package register
|
package register
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// register the overlay2 graphdriver
|
// register the overlay graphdriver
|
||||||
_ "github.com/containers/storage/drivers/overlay2"
|
_ "github.com/containers/storage/drivers/overlay"
|
||||||
)
|
)
|
||||||
|
|
2
vendor/github.com/containers/storage/hack/make/cross
generated
vendored
2
vendor/github.com/containers/storage/hack/make/cross
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
CROSSPLATFORMS="linux/amd64 linux/386 linux/arm"
|
CROSSPLATFORMS="linux/amd64 linux/386 linux/arm darwin/amd64"
|
||||||
BUILDTAGS+=" exclude_graphdriver_devicemapper"
|
BUILDTAGS+=" exclude_graphdriver_devicemapper"
|
||||||
|
|
||||||
for platform in $CROSSPLATFORMS; do
|
for platform in $CROSSPLATFORMS; do
|
||||||
|
|
137
vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
generated
vendored
Normal file
137
vendor/github.com/containers/storage/pkg/truncindex/truncindex.go
generated
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// Package truncindex provides a general 'index tree', used by Docker
|
||||||
|
// in order to be able to reference containers by only a few unambiguous
|
||||||
|
// characters of their id.
|
||||||
|
package truncindex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/tchap/go-patricia/patricia"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrEmptyPrefix is an error returned if the prefix was empty.
|
||||||
|
ErrEmptyPrefix = errors.New("Prefix can't be empty")
|
||||||
|
|
||||||
|
// ErrIllegalChar is returned when a space is in the ID
|
||||||
|
ErrIllegalChar = errors.New("illegal character: ' '")
|
||||||
|
|
||||||
|
// ErrNotExist is returned when ID or its prefix not found in index.
|
||||||
|
ErrNotExist = errors.New("ID does not exist")
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrAmbiguousPrefix is returned if the prefix was ambiguous
|
||||||
|
// (multiple ids for the prefix).
|
||||||
|
type ErrAmbiguousPrefix struct {
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e ErrAmbiguousPrefix) Error() string {
|
||||||
|
return fmt.Sprintf("Multiple IDs found with provided prefix: %s", e.prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TruncIndex allows the retrieval of string identifiers by any of their unique prefixes.
|
||||||
|
// This is used to retrieve image and container IDs by more convenient shorthand prefixes.
|
||||||
|
type TruncIndex struct {
|
||||||
|
sync.RWMutex
|
||||||
|
trie *patricia.Trie
|
||||||
|
ids map[string]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTruncIndex creates a new TruncIndex and initializes with a list of IDs.
|
||||||
|
func NewTruncIndex(ids []string) (idx *TruncIndex) {
|
||||||
|
idx = &TruncIndex{
|
||||||
|
ids: make(map[string]struct{}),
|
||||||
|
|
||||||
|
// Change patricia max prefix per node length,
|
||||||
|
// because our len(ID) always 64
|
||||||
|
trie: patricia.NewTrie(patricia.MaxPrefixPerNode(64)),
|
||||||
|
}
|
||||||
|
for _, id := range ids {
|
||||||
|
idx.addID(id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (idx *TruncIndex) addID(id string) error {
|
||||||
|
if strings.Contains(id, " ") {
|
||||||
|
return ErrIllegalChar
|
||||||
|
}
|
||||||
|
if id == "" {
|
||||||
|
return ErrEmptyPrefix
|
||||||
|
}
|
||||||
|
if _, exists := idx.ids[id]; exists {
|
||||||
|
return fmt.Errorf("id already exists: '%s'", id)
|
||||||
|
}
|
||||||
|
idx.ids[id] = struct{}{}
|
||||||
|
if inserted := idx.trie.Insert(patricia.Prefix(id), struct{}{}); !inserted {
|
||||||
|
return fmt.Errorf("failed to insert id: %s", id)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds a new ID to the TruncIndex.
|
||||||
|
func (idx *TruncIndex) Add(id string) error {
|
||||||
|
idx.Lock()
|
||||||
|
defer idx.Unlock()
|
||||||
|
if err := idx.addID(id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete removes an ID from the TruncIndex. If there are multiple IDs
|
||||||
|
// with the given prefix, an error is thrown.
|
||||||
|
func (idx *TruncIndex) Delete(id string) error {
|
||||||
|
idx.Lock()
|
||||||
|
defer idx.Unlock()
|
||||||
|
if _, exists := idx.ids[id]; !exists || id == "" {
|
||||||
|
return fmt.Errorf("no such id: '%s'", id)
|
||||||
|
}
|
||||||
|
delete(idx.ids, id)
|
||||||
|
if deleted := idx.trie.Delete(patricia.Prefix(id)); !deleted {
|
||||||
|
return fmt.Errorf("no such id: '%s'", id)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves an ID from the TruncIndex. If there are multiple IDs
|
||||||
|
// with the given prefix, an error is thrown.
|
||||||
|
func (idx *TruncIndex) Get(s string) (string, error) {
|
||||||
|
if s == "" {
|
||||||
|
return "", ErrEmptyPrefix
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
id string
|
||||||
|
)
|
||||||
|
subTreeVisitFunc := func(prefix patricia.Prefix, item patricia.Item) error {
|
||||||
|
if id != "" {
|
||||||
|
// we haven't found the ID if there are two or more IDs
|
||||||
|
id = ""
|
||||||
|
return ErrAmbiguousPrefix{prefix: string(prefix)}
|
||||||
|
}
|
||||||
|
id = string(prefix)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
idx.RLock()
|
||||||
|
defer idx.RUnlock()
|
||||||
|
if err := idx.trie.VisitSubtree(patricia.Prefix(s), subTreeVisitFunc); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if id != "" {
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
return "", ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate iterates over all stored IDs, and passes each of them to the given handler.
|
||||||
|
func (idx *TruncIndex) Iterate(handler func(id string)) {
|
||||||
|
idx.trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
|
||||||
|
handler(string(prefix))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
429
vendor/github.com/containers/storage/pkg/truncindex/truncindex_test.go
generated
vendored
Normal file
429
vendor/github.com/containers/storage/pkg/truncindex/truncindex_test.go
generated
vendored
Normal file
|
@ -0,0 +1,429 @@
|
||||||
|
package truncindex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containers/storage/pkg/stringid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Test the behavior of TruncIndex, an index for querying IDs from a non-conflicting prefix.
|
||||||
|
func TestTruncIndex(t *testing.T) {
|
||||||
|
ids := []string{}
|
||||||
|
index := NewTruncIndex(ids)
|
||||||
|
// Get on an empty index
|
||||||
|
if _, err := index.Get("foobar"); err == nil {
|
||||||
|
t.Fatal("Get on an empty index should return an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spaces should be illegal in an id
|
||||||
|
if err := index.Add("I have a space"); err == nil {
|
||||||
|
t.Fatalf("Adding an id with ' ' should return an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
id := "99b36c2c326ccc11e726eee6ee78a0baf166ef96"
|
||||||
|
// Add an id
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an empty id (should fail)
|
||||||
|
if err := index.Add(""); err == nil {
|
||||||
|
t.Fatalf("Adding an empty id should return an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a non-existing id
|
||||||
|
assertIndexGet(t, index, "abracadabra", "", true)
|
||||||
|
// Get an empty id
|
||||||
|
assertIndexGet(t, index, "", "", true)
|
||||||
|
// Get the exact id
|
||||||
|
assertIndexGet(t, index, id, id, false)
|
||||||
|
// The first letter should match
|
||||||
|
assertIndexGet(t, index, id[:1], id, false)
|
||||||
|
// The first half should match
|
||||||
|
assertIndexGet(t, index, id[:len(id)/2], id, false)
|
||||||
|
// The second half should NOT match
|
||||||
|
assertIndexGet(t, index, id[len(id)/2:], "", true)
|
||||||
|
|
||||||
|
id2 := id[:6] + "blabla"
|
||||||
|
// Add an id
|
||||||
|
if err := index.Add(id2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// Both exact IDs should work
|
||||||
|
assertIndexGet(t, index, id, id, false)
|
||||||
|
assertIndexGet(t, index, id2, id2, false)
|
||||||
|
|
||||||
|
// 6 characters or less should conflict
|
||||||
|
assertIndexGet(t, index, id[:6], "", true)
|
||||||
|
assertIndexGet(t, index, id[:4], "", true)
|
||||||
|
assertIndexGet(t, index, id[:1], "", true)
|
||||||
|
|
||||||
|
// An ambiguous id prefix should return an error
|
||||||
|
if _, err := index.Get(id[:4]); err == nil {
|
||||||
|
t.Fatal("An ambiguous id prefix should return an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7 characters should NOT conflict
|
||||||
|
assertIndexGet(t, index, id[:7], id, false)
|
||||||
|
assertIndexGet(t, index, id2[:7], id2, false)
|
||||||
|
|
||||||
|
// Deleting a non-existing id should return an error
|
||||||
|
if err := index.Delete("non-existing"); err == nil {
|
||||||
|
t.Fatalf("Deleting a non-existing id should return an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deleting an empty id should return an error
|
||||||
|
if err := index.Delete(""); err == nil {
|
||||||
|
t.Fatal("Deleting an empty id should return an error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deleting id2 should remove conflicts
|
||||||
|
if err := index.Delete(id2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// id2 should no longer work
|
||||||
|
assertIndexGet(t, index, id2, "", true)
|
||||||
|
assertIndexGet(t, index, id2[:7], "", true)
|
||||||
|
assertIndexGet(t, index, id2[:11], "", true)
|
||||||
|
|
||||||
|
// conflicts between id and id2 should be gone
|
||||||
|
assertIndexGet(t, index, id[:6], id, false)
|
||||||
|
assertIndexGet(t, index, id[:4], id, false)
|
||||||
|
assertIndexGet(t, index, id[:1], id, false)
|
||||||
|
|
||||||
|
// non-conflicting substrings should still not conflict
|
||||||
|
assertIndexGet(t, index, id[:7], id, false)
|
||||||
|
assertIndexGet(t, index, id[:15], id, false)
|
||||||
|
assertIndexGet(t, index, id, id, false)
|
||||||
|
|
||||||
|
assertIndexIterate(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertIndexIterate(t *testing.T) {
|
||||||
|
ids := []string{
|
||||||
|
"19b36c2c326ccc11e726eee6ee78a0baf166ef96",
|
||||||
|
"28b36c2c326ccc11e726eee6ee78a0baf166ef96",
|
||||||
|
"37b36c2c326ccc11e726eee6ee78a0baf166ef96",
|
||||||
|
"46b36c2c326ccc11e726eee6ee78a0baf166ef96",
|
||||||
|
}
|
||||||
|
|
||||||
|
index := NewTruncIndex(ids)
|
||||||
|
|
||||||
|
index.Iterate(func(targetId string) {
|
||||||
|
for _, id := range ids {
|
||||||
|
if targetId == id {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Fatalf("An unknown ID '%s'", targetId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertIndexGet(t *testing.T, index *TruncIndex, input, expectedResult string, expectError bool) {
|
||||||
|
if result, err := index.Get(input); err != nil && !expectError {
|
||||||
|
t.Fatalf("Unexpected error getting '%s': %s", input, err)
|
||||||
|
} else if err == nil && expectError {
|
||||||
|
t.Fatalf("Getting '%s' should return an error, not '%s'", input, result)
|
||||||
|
} else if result != expectedResult {
|
||||||
|
t.Fatalf("Getting '%s' returned '%s' instead of '%s'", input, result, expectedResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexAdd100(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexAdd250(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 250; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexAdd500(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexGet100(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
var testKeys []string
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
l := rand.Intn(12) + 12
|
||||||
|
testKeys = append(testKeys, id[:l])
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
for _, id := range testKeys {
|
||||||
|
if res, err := index.Get(id); err != nil {
|
||||||
|
b.Fatal(res, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexGet250(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
var testKeys []string
|
||||||
|
for i := 0; i < 250; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
l := rand.Intn(12) + 12
|
||||||
|
testKeys = append(testKeys, id[:l])
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
for _, id := range testKeys {
|
||||||
|
if res, err := index.Get(id); err != nil {
|
||||||
|
b.Fatal(res, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexGet500(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
var testKeys []string
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
l := rand.Intn(12) + 12
|
||||||
|
testKeys = append(testKeys, id[:l])
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
for _, id := range testKeys {
|
||||||
|
if res, err := index.Get(id); err != nil {
|
||||||
|
b.Fatal(res, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexDelete100(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Delete(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexDelete250(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 250; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Delete(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexDelete500(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Delete(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexNew100(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
NewTruncIndex(testSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexNew250(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 250; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
NewTruncIndex(testSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexNew500(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
testSet = append(testSet, stringid.GenerateNonCryptoID())
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
NewTruncIndex(testSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexAddGet100(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
var testKeys []string
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
id := stringid.GenerateNonCryptoID()
|
||||||
|
testSet = append(testSet, id)
|
||||||
|
l := rand.Intn(12) + 12
|
||||||
|
testKeys = append(testKeys, id[:l])
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, id := range testKeys {
|
||||||
|
if res, err := index.Get(id); err != nil {
|
||||||
|
b.Fatal(res, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexAddGet250(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
var testKeys []string
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
id := stringid.GenerateNonCryptoID()
|
||||||
|
testSet = append(testSet, id)
|
||||||
|
l := rand.Intn(12) + 12
|
||||||
|
testKeys = append(testKeys, id[:l])
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, id := range testKeys {
|
||||||
|
if res, err := index.Get(id); err != nil {
|
||||||
|
b.Fatal(res, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTruncIndexAddGet500(b *testing.B) {
|
||||||
|
var testSet []string
|
||||||
|
var testKeys []string
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
id := stringid.GenerateNonCryptoID()
|
||||||
|
testSet = append(testSet, id)
|
||||||
|
l := rand.Intn(12) + 12
|
||||||
|
testKeys = append(testKeys, id[:l])
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
index := NewTruncIndex([]string{})
|
||||||
|
for _, id := range testSet {
|
||||||
|
if err := index.Add(id); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, id := range testKeys {
|
||||||
|
if res, err := index.Get(id); err != nil {
|
||||||
|
b.Fatal(res, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
185
vendor/github.com/containers/storage/storage/containers.go
generated
vendored
185
vendor/github.com/containers/storage/storage/containers.go
generated
vendored
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
|
"github.com/containers/storage/pkg/truncindex"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -93,6 +94,7 @@ type containerStore struct {
|
||||||
lockfile Locker
|
lockfile Locker
|
||||||
dir string
|
dir string
|
||||||
containers []Container
|
containers []Container
|
||||||
|
idindex *truncindex.TruncIndex
|
||||||
byid map[string]*Container
|
byid map[string]*Container
|
||||||
bylayer map[string]*Container
|
bylayer map[string]*Container
|
||||||
byname map[string]*Container
|
byname map[string]*Container
|
||||||
|
@ -123,10 +125,12 @@ func (r *containerStore) Load() error {
|
||||||
}
|
}
|
||||||
containers := []Container{}
|
containers := []Container{}
|
||||||
layers := make(map[string]*Container)
|
layers := make(map[string]*Container)
|
||||||
|
idlist := []string{}
|
||||||
ids := make(map[string]*Container)
|
ids := make(map[string]*Container)
|
||||||
names := make(map[string]*Container)
|
names := make(map[string]*Container)
|
||||||
if err = json.Unmarshal(data, &containers); len(data) == 0 || err == nil {
|
if err = json.Unmarshal(data, &containers); len(data) == 0 || err == nil {
|
||||||
for n, container := range containers {
|
for n, container := range containers {
|
||||||
|
idlist = append(idlist, container.ID)
|
||||||
ids[container.ID] = &containers[n]
|
ids[container.ID] = &containers[n]
|
||||||
layers[container.LayerID] = &containers[n]
|
layers[container.LayerID] = &containers[n]
|
||||||
for _, name := range container.Names {
|
for _, name := range container.Names {
|
||||||
|
@ -139,6 +143,7 @@ func (r *containerStore) Load() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.containers = containers
|
r.containers = containers
|
||||||
|
r.idindex = truncindex.NewTruncIndex(idlist)
|
||||||
r.byid = ids
|
r.byid = ids
|
||||||
r.bylayer = layers
|
r.bylayer = layers
|
||||||
r.byname = names
|
r.byname = names
|
||||||
|
@ -185,30 +190,35 @@ func newContainerStore(dir string) (ContainerStore, error) {
|
||||||
return &cstore, nil
|
return &cstore, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) ClearFlag(id string, flag string) error {
|
func (r *containerStore) lookup(id string) (*Container, bool) {
|
||||||
if container, ok := r.byname[id]; ok {
|
if container, ok := r.byid[id]; ok {
|
||||||
id = container.ID
|
return container, ok
|
||||||
|
} else if container, ok := r.byname[id]; ok {
|
||||||
|
return container, ok
|
||||||
} else if container, ok := r.bylayer[id]; ok {
|
} else if container, ok := r.bylayer[id]; ok {
|
||||||
id = container.ID
|
return container, ok
|
||||||
|
} else if longid, err := r.idindex.Get(id); err == nil {
|
||||||
|
if container, ok := r.byid[longid]; ok {
|
||||||
|
return container, ok
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if _, ok := r.byid[id]; !ok {
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *containerStore) ClearFlag(id string, flag string) error {
|
||||||
|
container, ok := r.lookup(id)
|
||||||
|
if !ok {
|
||||||
return ErrContainerUnknown
|
return ErrContainerUnknown
|
||||||
}
|
}
|
||||||
container := r.byid[id]
|
|
||||||
delete(container.Flags, flag)
|
delete(container.Flags, flag)
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) SetFlag(id string, flag string, value interface{}) error {
|
func (r *containerStore) SetFlag(id string, flag string, value interface{}) error {
|
||||||
if container, ok := r.byname[id]; ok {
|
container, ok := r.lookup(id)
|
||||||
id = container.ID
|
if !ok {
|
||||||
} else if container, ok := r.bylayer[id]; ok {
|
|
||||||
id = container.ID
|
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrContainerUnknown
|
return ErrContainerUnknown
|
||||||
}
|
}
|
||||||
container := r.byid[id]
|
|
||||||
container.Flags[flag] = value
|
container.Flags[flag] = value
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
@ -244,6 +254,7 @@ func (r *containerStore) Create(id string, names []string, image, layer, metadat
|
||||||
r.containers = append(r.containers, newContainer)
|
r.containers = append(r.containers, newContainer)
|
||||||
container = &r.containers[len(r.containers)-1]
|
container = &r.containers[len(r.containers)-1]
|
||||||
r.byid[id] = container
|
r.byid[id] = container
|
||||||
|
r.idindex.Add(id)
|
||||||
r.bylayer[layer] = container
|
r.bylayer[layer] = container
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
r.byname[name] = container
|
r.byname[name] = container
|
||||||
|
@ -254,24 +265,14 @@ func (r *containerStore) Create(id string, names []string, image, layer, metadat
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) GetMetadata(id string) (string, error) {
|
func (r *containerStore) GetMetadata(id string) (string, error) {
|
||||||
if container, ok := r.byname[id]; ok {
|
if container, ok := r.lookup(id); ok {
|
||||||
id = container.ID
|
|
||||||
} else if container, ok := r.bylayer[id]; ok {
|
|
||||||
id = container.ID
|
|
||||||
}
|
|
||||||
if container, ok := r.byid[id]; ok {
|
|
||||||
return container.Metadata, nil
|
return container.Metadata, nil
|
||||||
}
|
}
|
||||||
return "", ErrContainerUnknown
|
return "", ErrContainerUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) SetMetadata(id, metadata string) error {
|
func (r *containerStore) SetMetadata(id, metadata string) error {
|
||||||
if container, ok := r.byname[id]; ok {
|
if container, ok := r.lookup(id); ok {
|
||||||
id = container.ID
|
|
||||||
} else if container, ok := r.bylayer[id]; ok {
|
|
||||||
id = container.ID
|
|
||||||
}
|
|
||||||
if container, ok := r.byid[id]; ok {
|
|
||||||
container.Metadata = metadata
|
container.Metadata = metadata
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
@ -279,22 +280,11 @@ func (r *containerStore) SetMetadata(id, metadata string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) removeName(container *Container, name string) {
|
func (r *containerStore) removeName(container *Container, name string) {
|
||||||
newNames := []string{}
|
container.Names = stringSliceWithoutValue(container.Names, name)
|
||||||
for _, oldName := range container.Names {
|
|
||||||
if oldName != name {
|
|
||||||
newNames = append(newNames, oldName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
container.Names = newNames
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) SetNames(id string, names []string) error {
|
func (r *containerStore) SetNames(id string, names []string) error {
|
||||||
if container, ok := r.byname[id]; ok {
|
if container, ok := r.lookup(id); ok {
|
||||||
id = container.ID
|
|
||||||
} else if container, ok := r.bylayer[id]; ok {
|
|
||||||
id = container.ID
|
|
||||||
}
|
|
||||||
if container, ok := r.byid[id]; ok {
|
|
||||||
for _, name := range container.Names {
|
for _, name := range container.Names {
|
||||||
delete(r.byname, name)
|
delete(r.byname, name)
|
||||||
}
|
}
|
||||||
|
@ -311,133 +301,104 @@ func (r *containerStore) SetNames(id string, names []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) Delete(id string) error {
|
func (r *containerStore) Delete(id string) error {
|
||||||
if container, ok := r.byname[id]; ok {
|
container, ok := r.lookup(id)
|
||||||
id = container.ID
|
if !ok {
|
||||||
} else if container, ok := r.bylayer[id]; ok {
|
|
||||||
id = container.ID
|
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrContainerUnknown
|
return ErrContainerUnknown
|
||||||
}
|
}
|
||||||
if container, ok := r.byid[id]; ok {
|
id = container.ID
|
||||||
newContainers := []Container{}
|
newContainers := []Container{}
|
||||||
for _, candidate := range r.containers {
|
for _, candidate := range r.containers {
|
||||||
if candidate.ID != id {
|
if candidate.ID != id {
|
||||||
newContainers = append(newContainers, candidate)
|
newContainers = append(newContainers, candidate)
|
||||||
}
|
|
||||||
}
|
|
||||||
delete(r.byid, container.ID)
|
|
||||||
delete(r.bylayer, container.LayerID)
|
|
||||||
for _, name := range container.Names {
|
|
||||||
delete(r.byname, name)
|
|
||||||
}
|
|
||||||
r.containers = newContainers
|
|
||||||
if err := r.Save(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.RemoveAll(r.datadir(id)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete(r.byid, id)
|
||||||
|
r.idindex.Delete(id)
|
||||||
|
delete(r.bylayer, container.LayerID)
|
||||||
|
for _, name := range container.Names {
|
||||||
|
delete(r.byname, name)
|
||||||
|
}
|
||||||
|
r.containers = newContainers
|
||||||
|
if err := r.Save(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.RemoveAll(r.datadir(id)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) Get(id string) (*Container, error) {
|
func (r *containerStore) Get(id string) (*Container, error) {
|
||||||
if c, ok := r.byname[id]; ok {
|
if container, ok := r.lookup(id); ok {
|
||||||
return c, nil
|
return container, nil
|
||||||
} else if c, ok := r.bylayer[id]; ok {
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
if c, ok := r.byid[id]; ok {
|
|
||||||
return c, nil
|
|
||||||
}
|
}
|
||||||
return nil, ErrContainerUnknown
|
return nil, ErrContainerUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) Lookup(name string) (id string, err error) {
|
func (r *containerStore) Lookup(name string) (id string, err error) {
|
||||||
container, ok := r.byname[name]
|
if container, ok := r.lookup(name); ok {
|
||||||
if !ok {
|
return container.ID, nil
|
||||||
container, ok = r.byid[name]
|
|
||||||
if !ok {
|
|
||||||
return "", ErrContainerUnknown
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return container.ID, nil
|
return "", ErrContainerUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) Exists(id string) bool {
|
func (r *containerStore) Exists(id string) bool {
|
||||||
if _, ok := r.byname[id]; ok {
|
_, ok := r.lookup(id)
|
||||||
return true
|
return ok
|
||||||
}
|
|
||||||
if _, ok := r.bylayer[id]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) GetBigData(id, key string) ([]byte, error) {
|
func (r *containerStore) GetBigData(id, key string) ([]byte, error) {
|
||||||
if img, ok := r.byname[id]; ok {
|
c, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return nil, ErrContainerUnknown
|
return nil, ErrContainerUnknown
|
||||||
}
|
}
|
||||||
return ioutil.ReadFile(r.datapath(id, key))
|
return ioutil.ReadFile(r.datapath(c.ID, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) GetBigDataSize(id, key string) (int64, error) {
|
func (r *containerStore) GetBigDataSize(id, key string) (int64, error) {
|
||||||
if img, ok := r.byname[id]; ok {
|
c, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return -1, ErrContainerUnknown
|
return -1, ErrContainerUnknown
|
||||||
}
|
}
|
||||||
if size, ok := r.byid[id].BigDataSizes[key]; ok {
|
if size, ok := c.BigDataSizes[key]; ok {
|
||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
return -1, ErrSizeUnknown
|
return -1, ErrSizeUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) GetBigDataNames(id string) ([]string, error) {
|
func (r *containerStore) GetBigDataNames(id string) ([]string, error) {
|
||||||
if img, ok := r.byname[id]; ok {
|
c, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return nil, ErrContainerUnknown
|
return nil, ErrContainerUnknown
|
||||||
}
|
}
|
||||||
return r.byid[id].BigDataNames, nil
|
return c.BigDataNames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *containerStore) SetBigData(id, key string, data []byte) error {
|
func (r *containerStore) SetBigData(id, key string, data []byte) error {
|
||||||
if img, ok := r.byname[id]; ok {
|
c, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrContainerUnknown
|
return ErrContainerUnknown
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(r.datadir(id), 0700); err != nil {
|
if err := os.MkdirAll(r.datadir(c.ID), 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err := ioutils.AtomicWriteFile(r.datapath(id, key), data, 0600)
|
err := ioutils.AtomicWriteFile(r.datapath(c.ID, key), data, 0600)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
save := false
|
save := false
|
||||||
oldSize, ok := r.byid[id].BigDataSizes[key]
|
oldSize, ok := c.BigDataSizes[key]
|
||||||
r.byid[id].BigDataSizes[key] = int64(len(data))
|
c.BigDataSizes[key] = int64(len(data))
|
||||||
if !ok || oldSize != r.byid[id].BigDataSizes[key] {
|
if !ok || oldSize != c.BigDataSizes[key] {
|
||||||
save = true
|
save = true
|
||||||
}
|
}
|
||||||
add := true
|
add := true
|
||||||
for _, name := range r.byid[id].BigDataNames {
|
for _, name := range c.BigDataNames {
|
||||||
if name == key {
|
if name == key {
|
||||||
add = false
|
add = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if add {
|
if add {
|
||||||
r.byid[id].BigDataNames = append(r.byid[id].BigDataNames, key)
|
c.BigDataNames = append(c.BigDataNames, key)
|
||||||
save = true
|
save = true
|
||||||
}
|
}
|
||||||
if save {
|
if save {
|
||||||
|
|
163
vendor/github.com/containers/storage/storage/images.go
generated
vendored
163
vendor/github.com/containers/storage/storage/images.go
generated
vendored
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
|
"github.com/containers/storage/pkg/truncindex"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -88,6 +89,7 @@ type imageStore struct {
|
||||||
lockfile Locker
|
lockfile Locker
|
||||||
dir string
|
dir string
|
||||||
images []Image
|
images []Image
|
||||||
|
idindex *truncindex.TruncIndex
|
||||||
byid map[string]*Image
|
byid map[string]*Image
|
||||||
byname map[string]*Image
|
byname map[string]*Image
|
||||||
}
|
}
|
||||||
|
@ -116,11 +118,13 @@ func (r *imageStore) Load() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
images := []Image{}
|
images := []Image{}
|
||||||
|
idlist := []string{}
|
||||||
ids := make(map[string]*Image)
|
ids := make(map[string]*Image)
|
||||||
names := make(map[string]*Image)
|
names := make(map[string]*Image)
|
||||||
if err = json.Unmarshal(data, &images); len(data) == 0 || err == nil {
|
if err = json.Unmarshal(data, &images); len(data) == 0 || err == nil {
|
||||||
for n, image := range images {
|
for n, image := range images {
|
||||||
ids[image.ID] = &images[n]
|
ids[image.ID] = &images[n]
|
||||||
|
idlist = append(idlist, image.ID)
|
||||||
for _, name := range image.Names {
|
for _, name := range image.Names {
|
||||||
if conflict, ok := names[name]; ok {
|
if conflict, ok := names[name]; ok {
|
||||||
r.removeName(conflict, name)
|
r.removeName(conflict, name)
|
||||||
|
@ -131,6 +135,7 @@ func (r *imageStore) Load() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.images = images
|
r.images = images
|
||||||
|
r.idindex = truncindex.NewTruncIndex(idlist)
|
||||||
r.byid = ids
|
r.byid = ids
|
||||||
r.byname = names
|
r.byname = names
|
||||||
if needSave {
|
if needSave {
|
||||||
|
@ -175,26 +180,32 @@ func newImageStore(dir string) (ImageStore, error) {
|
||||||
return &istore, nil
|
return &istore, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) ClearFlag(id string, flag string) error {
|
func (r *imageStore) lookup(id string) (*Image, bool) {
|
||||||
if image, ok := r.byname[id]; ok {
|
if image, ok := r.byid[id]; ok {
|
||||||
id = image.ID
|
return image, ok
|
||||||
|
} else if image, ok := r.byname[id]; ok {
|
||||||
|
return image, ok
|
||||||
|
} else if longid, err := r.idindex.Get(id); err == nil {
|
||||||
|
image, ok := r.byid[longid]
|
||||||
|
return image, ok
|
||||||
}
|
}
|
||||||
if _, ok := r.byid[id]; !ok {
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *imageStore) ClearFlag(id string, flag string) error {
|
||||||
|
image, ok := r.lookup(id)
|
||||||
|
if !ok {
|
||||||
return ErrImageUnknown
|
return ErrImageUnknown
|
||||||
}
|
}
|
||||||
image := r.byid[id]
|
|
||||||
delete(image.Flags, flag)
|
delete(image.Flags, flag)
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) SetFlag(id string, flag string, value interface{}) error {
|
func (r *imageStore) SetFlag(id string, flag string, value interface{}) error {
|
||||||
if image, ok := r.byname[id]; ok {
|
image, ok := r.lookup(id)
|
||||||
id = image.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrImageUnknown
|
return ErrImageUnknown
|
||||||
}
|
}
|
||||||
image := r.byid[id]
|
|
||||||
image.Flags[flag] = value
|
image.Flags[flag] = value
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
@ -228,6 +239,7 @@ func (r *imageStore) Create(id string, names []string, layer, metadata string) (
|
||||||
}
|
}
|
||||||
r.images = append(r.images, newImage)
|
r.images = append(r.images, newImage)
|
||||||
image = &r.images[len(r.images)-1]
|
image = &r.images[len(r.images)-1]
|
||||||
|
r.idindex.Add(id)
|
||||||
r.byid[id] = image
|
r.byid[id] = image
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
r.byname[name] = image
|
r.byname[name] = image
|
||||||
|
@ -238,20 +250,14 @@ func (r *imageStore) Create(id string, names []string, layer, metadata string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) GetMetadata(id string) (string, error) {
|
func (r *imageStore) GetMetadata(id string) (string, error) {
|
||||||
if image, ok := r.byname[id]; ok {
|
if image, ok := r.lookup(id); ok {
|
||||||
id = image.ID
|
|
||||||
}
|
|
||||||
if image, ok := r.byid[id]; ok {
|
|
||||||
return image.Metadata, nil
|
return image.Metadata, nil
|
||||||
}
|
}
|
||||||
return "", ErrImageUnknown
|
return "", ErrImageUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) SetMetadata(id, metadata string) error {
|
func (r *imageStore) SetMetadata(id, metadata string) error {
|
||||||
if image, ok := r.byname[id]; ok {
|
if image, ok := r.lookup(id); ok {
|
||||||
id = image.ID
|
|
||||||
}
|
|
||||||
if image, ok := r.byid[id]; ok {
|
|
||||||
image.Metadata = metadata
|
image.Metadata = metadata
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
@ -259,20 +265,11 @@ func (r *imageStore) SetMetadata(id, metadata string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) removeName(image *Image, name string) {
|
func (r *imageStore) removeName(image *Image, name string) {
|
||||||
newNames := []string{}
|
image.Names = stringSliceWithoutValue(image.Names, name)
|
||||||
for _, oldName := range image.Names {
|
|
||||||
if oldName != name {
|
|
||||||
newNames = append(newNames, oldName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
image.Names = newNames
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) SetNames(id string, names []string) error {
|
func (r *imageStore) SetNames(id string, names []string) error {
|
||||||
if image, ok := r.byname[id]; ok {
|
if image, ok := r.lookup(id); ok {
|
||||||
id = image.ID
|
|
||||||
}
|
|
||||||
if image, ok := r.byid[id]; ok {
|
|
||||||
for _, name := range image.Names {
|
for _, name := range image.Names {
|
||||||
delete(r.byname, name)
|
delete(r.byname, name)
|
||||||
}
|
}
|
||||||
|
@ -289,125 +286,103 @@ func (r *imageStore) SetNames(id string, names []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) Delete(id string) error {
|
func (r *imageStore) Delete(id string) error {
|
||||||
if image, ok := r.byname[id]; ok {
|
image, ok := r.lookup(id)
|
||||||
id = image.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrImageUnknown
|
return ErrImageUnknown
|
||||||
}
|
}
|
||||||
if image, ok := r.byid[id]; ok {
|
id = image.ID
|
||||||
newImages := []Image{}
|
newImages := []Image{}
|
||||||
for _, candidate := range r.images {
|
for _, candidate := range r.images {
|
||||||
if candidate.ID != id {
|
if candidate.ID != id {
|
||||||
newImages = append(newImages, candidate)
|
newImages = append(newImages, candidate)
|
||||||
}
|
|
||||||
}
|
|
||||||
delete(r.byid, image.ID)
|
|
||||||
for _, name := range image.Names {
|
|
||||||
delete(r.byname, name)
|
|
||||||
}
|
|
||||||
r.images = newImages
|
|
||||||
if err := r.Save(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.RemoveAll(r.datadir(id)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete(r.byid, id)
|
||||||
|
r.idindex.Delete(id)
|
||||||
|
for _, name := range image.Names {
|
||||||
|
delete(r.byname, name)
|
||||||
|
}
|
||||||
|
r.images = newImages
|
||||||
|
if err := r.Save(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.RemoveAll(r.datadir(id)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) Get(id string) (*Image, error) {
|
func (r *imageStore) Get(id string) (*Image, error) {
|
||||||
if image, ok := r.byname[id]; ok {
|
if image, ok := r.lookup(id); ok {
|
||||||
return image, nil
|
|
||||||
}
|
|
||||||
if image, ok := r.byid[id]; ok {
|
|
||||||
return image, nil
|
return image, nil
|
||||||
}
|
}
|
||||||
return nil, ErrImageUnknown
|
return nil, ErrImageUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) Lookup(name string) (id string, err error) {
|
func (r *imageStore) Lookup(name string) (id string, err error) {
|
||||||
image, ok := r.byname[name]
|
if image, ok := r.lookup(name); ok {
|
||||||
if !ok {
|
return image.ID, nil
|
||||||
image, ok = r.byid[name]
|
|
||||||
if !ok {
|
|
||||||
return "", ErrImageUnknown
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return image.ID, nil
|
return "", ErrImageUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) Exists(id string) bool {
|
func (r *imageStore) Exists(id string) bool {
|
||||||
if _, ok := r.byname[id]; ok {
|
_, ok := r.lookup(id)
|
||||||
return true
|
return ok
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) GetBigData(id, key string) ([]byte, error) {
|
func (r *imageStore) GetBigData(id, key string) ([]byte, error) {
|
||||||
if img, ok := r.byname[id]; ok {
|
image, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return nil, ErrImageUnknown
|
return nil, ErrImageUnknown
|
||||||
}
|
}
|
||||||
return ioutil.ReadFile(r.datapath(id, key))
|
return ioutil.ReadFile(r.datapath(image.ID, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) GetBigDataSize(id, key string) (int64, error) {
|
func (r *imageStore) GetBigDataSize(id, key string) (int64, error) {
|
||||||
if img, ok := r.byname[id]; ok {
|
image, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return -1, ErrImageUnknown
|
return -1, ErrImageUnknown
|
||||||
}
|
}
|
||||||
if size, ok := r.byid[id].BigDataSizes[key]; ok {
|
if size, ok := image.BigDataSizes[key]; ok {
|
||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
return -1, ErrSizeUnknown
|
return -1, ErrSizeUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) GetBigDataNames(id string) ([]string, error) {
|
func (r *imageStore) GetBigDataNames(id string) ([]string, error) {
|
||||||
if img, ok := r.byname[id]; ok {
|
image, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return nil, ErrImageUnknown
|
return nil, ErrImageUnknown
|
||||||
}
|
}
|
||||||
return r.byid[id].BigDataNames, nil
|
return image.BigDataNames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageStore) SetBigData(id, key string, data []byte) error {
|
func (r *imageStore) SetBigData(id, key string, data []byte) error {
|
||||||
if img, ok := r.byname[id]; ok {
|
image, ok := r.lookup(id)
|
||||||
id = img.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrImageUnknown
|
return ErrImageUnknown
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(r.datadir(id), 0700); err != nil {
|
if err := os.MkdirAll(r.datadir(image.ID), 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err := ioutils.AtomicWriteFile(r.datapath(id, key), data, 0600)
|
err := ioutils.AtomicWriteFile(r.datapath(image.ID, key), data, 0600)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
add := true
|
add := true
|
||||||
save := false
|
save := false
|
||||||
oldSize, ok := r.byid[id].BigDataSizes[key]
|
oldSize, ok := image.BigDataSizes[key]
|
||||||
r.byid[id].BigDataSizes[key] = int64(len(data))
|
image.BigDataSizes[key] = int64(len(data))
|
||||||
if !ok || oldSize != r.byid[id].BigDataSizes[key] {
|
if !ok || oldSize != image.BigDataSizes[key] {
|
||||||
save = true
|
save = true
|
||||||
}
|
}
|
||||||
for _, name := range r.byid[id].BigDataNames {
|
for _, name := range image.BigDataNames {
|
||||||
if name == key {
|
if name == key {
|
||||||
add = false
|
add = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if add {
|
if add {
|
||||||
r.byid[id].BigDataNames = append(r.byid[id].BigDataNames, key)
|
image.BigDataNames = append(image.BigDataNames, key)
|
||||||
save = true
|
save = true
|
||||||
}
|
}
|
||||||
if save {
|
if save {
|
||||||
|
|
267
vendor/github.com/containers/storage/storage/layers.go
generated
vendored
267
vendor/github.com/containers/storage/storage/layers.go
generated
vendored
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/containers/storage/pkg/archive"
|
"github.com/containers/storage/pkg/archive"
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
|
"github.com/containers/storage/pkg/truncindex"
|
||||||
"github.com/vbatts/tar-split/tar/asm"
|
"github.com/vbatts/tar-split/tar/asm"
|
||||||
"github.com/vbatts/tar-split/tar/storage"
|
"github.com/vbatts/tar-split/tar/storage"
|
||||||
)
|
)
|
||||||
|
@ -159,6 +160,7 @@ type layerStore struct {
|
||||||
driver drivers.Driver
|
driver drivers.Driver
|
||||||
layerdir string
|
layerdir string
|
||||||
layers []Layer
|
layers []Layer
|
||||||
|
idindex *truncindex.TruncIndex
|
||||||
byid map[string]*Layer
|
byid map[string]*Layer
|
||||||
byname map[string]*Layer
|
byname map[string]*Layer
|
||||||
byparent map[string][]*Layer
|
byparent map[string][]*Layer
|
||||||
|
@ -185,6 +187,7 @@ func (r *layerStore) Load() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
layers := []Layer{}
|
layers := []Layer{}
|
||||||
|
idlist := []string{}
|
||||||
ids := make(map[string]*Layer)
|
ids := make(map[string]*Layer)
|
||||||
names := make(map[string]*Layer)
|
names := make(map[string]*Layer)
|
||||||
mounts := make(map[string]*Layer)
|
mounts := make(map[string]*Layer)
|
||||||
|
@ -192,6 +195,7 @@ func (r *layerStore) Load() error {
|
||||||
if err = json.Unmarshal(data, &layers); len(data) == 0 || err == nil {
|
if err = json.Unmarshal(data, &layers); len(data) == 0 || err == nil {
|
||||||
for n, layer := range layers {
|
for n, layer := range layers {
|
||||||
ids[layer.ID] = &layers[n]
|
ids[layer.ID] = &layers[n]
|
||||||
|
idlist = append(idlist, layer.ID)
|
||||||
for _, name := range layer.Names {
|
for _, name := range layer.Names {
|
||||||
if conflict, ok := names[name]; ok {
|
if conflict, ok := names[name]; ok {
|
||||||
r.removeName(conflict, name)
|
r.removeName(conflict, name)
|
||||||
|
@ -224,6 +228,7 @@ func (r *layerStore) Load() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.layers = layers
|
r.layers = layers
|
||||||
|
r.idindex = truncindex.NewTruncIndex(idlist)
|
||||||
r.byid = ids
|
r.byid = ids
|
||||||
r.byname = names
|
r.byname = names
|
||||||
r.byparent = parents
|
r.byparent = parents
|
||||||
|
@ -312,26 +317,32 @@ func newLayerStore(rundir string, layerdir string, driver drivers.Driver) (Layer
|
||||||
return &rlstore, nil
|
return &rlstore, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) ClearFlag(id string, flag string) error {
|
func (r *layerStore) lookup(id string) (*Layer, bool) {
|
||||||
if layer, ok := r.byname[id]; ok {
|
if layer, ok := r.byid[id]; ok {
|
||||||
id = layer.ID
|
return layer, ok
|
||||||
|
} else if layer, ok := r.byname[id]; ok {
|
||||||
|
return layer, ok
|
||||||
|
} else if longid, err := r.idindex.Get(id); err == nil {
|
||||||
|
layer, ok := r.byid[longid]
|
||||||
|
return layer, ok
|
||||||
}
|
}
|
||||||
if _, ok := r.byid[id]; !ok {
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *layerStore) ClearFlag(id string, flag string) error {
|
||||||
|
layer, ok := r.lookup(id)
|
||||||
|
if !ok {
|
||||||
return ErrLayerUnknown
|
return ErrLayerUnknown
|
||||||
}
|
}
|
||||||
layer := r.byid[id]
|
|
||||||
delete(layer.Flags, flag)
|
delete(layer.Flags, flag)
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) SetFlag(id string, flag string, value interface{}) error {
|
func (r *layerStore) SetFlag(id string, flag string, value interface{}) error {
|
||||||
if layer, ok := r.byname[id]; ok {
|
layer, ok := r.lookup(id)
|
||||||
id = layer.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrLayerUnknown
|
return ErrLayerUnknown
|
||||||
}
|
}
|
||||||
layer := r.byid[id]
|
|
||||||
layer.Flags[flag] = value
|
layer.Flags[flag] = value
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
@ -348,8 +359,10 @@ func (r *layerStore) Put(id, parent string, names []string, mountLabel string, o
|
||||||
if err := os.MkdirAll(r.layerdir, 0700); err != nil {
|
if err := os.MkdirAll(r.layerdir, 0700); err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
}
|
}
|
||||||
if parentLayer, ok := r.byname[parent]; ok {
|
if parent != "" {
|
||||||
parent = parentLayer.ID
|
if parentLayer, ok := r.lookup(parent); ok {
|
||||||
|
parent = parentLayer.ID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if id == "" {
|
if id == "" {
|
||||||
id = stringid.GenerateRandomID()
|
id = stringid.GenerateRandomID()
|
||||||
|
@ -382,6 +395,7 @@ func (r *layerStore) Put(id, parent string, names []string, mountLabel string, o
|
||||||
}
|
}
|
||||||
r.layers = append(r.layers, newLayer)
|
r.layers = append(r.layers, newLayer)
|
||||||
layer = &r.layers[len(r.layers)-1]
|
layer = &r.layers[len(r.layers)-1]
|
||||||
|
r.idindex.Add(id)
|
||||||
r.byid[id] = layer
|
r.byid[id] = layer
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
r.byname[name] = layer
|
r.byname[name] = layer
|
||||||
|
@ -436,48 +450,39 @@ func (r *layerStore) Create(id, parent string, names []string, mountLabel string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Mount(id, mountLabel string) (string, error) {
|
func (r *layerStore) Mount(id, mountLabel string) (string, error) {
|
||||||
if layer, ok := r.byname[id]; ok {
|
layer, ok := r.lookup(id)
|
||||||
id = layer.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return "", ErrLayerUnknown
|
return "", ErrLayerUnknown
|
||||||
}
|
}
|
||||||
layer := r.byid[id]
|
|
||||||
if layer.MountCount > 0 {
|
if layer.MountCount > 0 {
|
||||||
layer.MountCount++
|
layer.MountCount++
|
||||||
return layer.MountPoint, r.Save()
|
return layer.MountPoint, r.Save()
|
||||||
}
|
}
|
||||||
if mountLabel == "" {
|
if mountLabel == "" {
|
||||||
if layer, ok := r.byid[id]; ok {
|
mountLabel = layer.MountLabel
|
||||||
mountLabel = layer.MountLabel
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mountpoint, err := r.driver.Get(id, mountLabel)
|
mountpoint, err := r.driver.Get(id, mountLabel)
|
||||||
if mountpoint != "" && err == nil {
|
if mountpoint != "" && err == nil {
|
||||||
if layer, ok := r.byid[id]; ok {
|
if layer.MountPoint != "" {
|
||||||
if layer.MountPoint != "" {
|
delete(r.bymount, layer.MountPoint)
|
||||||
delete(r.bymount, layer.MountPoint)
|
|
||||||
}
|
|
||||||
layer.MountPoint = filepath.Clean(mountpoint)
|
|
||||||
layer.MountCount++
|
|
||||||
r.bymount[layer.MountPoint] = layer
|
|
||||||
err = r.Save()
|
|
||||||
}
|
}
|
||||||
|
layer.MountPoint = filepath.Clean(mountpoint)
|
||||||
|
layer.MountCount++
|
||||||
|
r.bymount[layer.MountPoint] = layer
|
||||||
|
err = r.Save()
|
||||||
}
|
}
|
||||||
return mountpoint, err
|
return mountpoint, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Unmount(id string) error {
|
func (r *layerStore) Unmount(id string) error {
|
||||||
if layer, ok := r.bymount[filepath.Clean(id)]; ok {
|
layer, ok := r.lookup(id)
|
||||||
id = layer.ID
|
if !ok {
|
||||||
|
layerByMount, ok := r.bymount[filepath.Clean(id)]
|
||||||
|
if !ok {
|
||||||
|
return ErrLayerUnknown
|
||||||
|
}
|
||||||
|
layer = layerByMount
|
||||||
}
|
}
|
||||||
if layer, ok := r.byname[id]; ok {
|
|
||||||
id = layer.ID
|
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrLayerUnknown
|
|
||||||
}
|
|
||||||
layer := r.byid[id]
|
|
||||||
if layer.MountCount > 1 {
|
if layer.MountCount > 1 {
|
||||||
layer.MountCount--
|
layer.MountCount--
|
||||||
return r.Save()
|
return r.Save()
|
||||||
|
@ -495,20 +500,11 @@ func (r *layerStore) Unmount(id string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) removeName(layer *Layer, name string) {
|
func (r *layerStore) removeName(layer *Layer, name string) {
|
||||||
newNames := []string{}
|
layer.Names = stringSliceWithoutValue(layer.Names, name)
|
||||||
for _, oldName := range layer.Names {
|
|
||||||
if oldName != name {
|
|
||||||
newNames = append(newNames, oldName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
layer.Names = newNames
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) SetNames(id string, names []string) error {
|
func (r *layerStore) SetNames(id string, names []string) error {
|
||||||
if layer, ok := r.byname[id]; ok {
|
if layer, ok := r.lookup(id); ok {
|
||||||
id = layer.ID
|
|
||||||
}
|
|
||||||
if layer, ok := r.byid[id]; ok {
|
|
||||||
for _, name := range layer.Names {
|
for _, name := range layer.Names {
|
||||||
delete(r.byname, name)
|
delete(r.byname, name)
|
||||||
}
|
}
|
||||||
|
@ -525,20 +521,14 @@ func (r *layerStore) SetNames(id string, names []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) GetMetadata(id string) (string, error) {
|
func (r *layerStore) GetMetadata(id string) (string, error) {
|
||||||
if layer, ok := r.byname[id]; ok {
|
if layer, ok := r.lookup(id); ok {
|
||||||
id = layer.ID
|
|
||||||
}
|
|
||||||
if layer, ok := r.byid[id]; ok {
|
|
||||||
return layer.Metadata, nil
|
return layer.Metadata, nil
|
||||||
}
|
}
|
||||||
return "", ErrLayerUnknown
|
return "", ErrLayerUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) SetMetadata(id, metadata string) error {
|
func (r *layerStore) SetMetadata(id, metadata string) error {
|
||||||
if layer, ok := r.byname[id]; ok {
|
if layer, ok := r.lookup(id); ok {
|
||||||
id = layer.ID
|
|
||||||
}
|
|
||||||
if layer, ok := r.byid[id]; ok {
|
|
||||||
layer.Metadata = metadata
|
layer.Metadata = metadata
|
||||||
return r.Save()
|
return r.Save()
|
||||||
}
|
}
|
||||||
|
@ -550,13 +540,12 @@ func (r *layerStore) tspath(id string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Delete(id string) error {
|
func (r *layerStore) Delete(id string) error {
|
||||||
if layer, ok := r.byname[id]; ok {
|
layer, ok := r.lookup(id)
|
||||||
id = layer.ID
|
if !ok {
|
||||||
}
|
|
||||||
if _, ok := r.byid[id]; !ok {
|
|
||||||
return ErrLayerUnknown
|
return ErrLayerUnknown
|
||||||
}
|
}
|
||||||
for r.byid[id].MountCount > 0 {
|
id = layer.ID
|
||||||
|
for layer.MountCount > 0 {
|
||||||
if err := r.Unmount(id); err != nil {
|
if err := r.Unmount(id); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -564,66 +553,55 @@ func (r *layerStore) Delete(id string) error {
|
||||||
err := r.driver.Remove(id)
|
err := r.driver.Remove(id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
os.Remove(r.tspath(id))
|
os.Remove(r.tspath(id))
|
||||||
if layer, ok := r.byid[id]; ok {
|
pslice := r.byparent[layer.Parent]
|
||||||
pslice := r.byparent[layer.Parent]
|
newPslice := []*Layer{}
|
||||||
newPslice := []*Layer{}
|
for _, candidate := range pslice {
|
||||||
for _, candidate := range pslice {
|
if candidate.ID != id {
|
||||||
if candidate.ID != id {
|
newPslice = append(newPslice, candidate)
|
||||||
newPslice = append(newPslice, candidate)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete(r.byid, layer.ID)
|
}
|
||||||
if len(newPslice) > 0 {
|
delete(r.byid, id)
|
||||||
r.byparent[layer.Parent] = newPslice
|
r.idindex.Delete(id)
|
||||||
} else {
|
if len(newPslice) > 0 {
|
||||||
delete(r.byparent, layer.Parent)
|
r.byparent[layer.Parent] = newPslice
|
||||||
}
|
} else {
|
||||||
for _, name := range layer.Names {
|
delete(r.byparent, layer.Parent)
|
||||||
delete(r.byname, name)
|
}
|
||||||
}
|
for _, name := range layer.Names {
|
||||||
if layer.MountPoint != "" {
|
delete(r.byname, name)
|
||||||
delete(r.bymount, layer.MountPoint)
|
}
|
||||||
}
|
if layer.MountPoint != "" {
|
||||||
newLayers := []Layer{}
|
delete(r.bymount, layer.MountPoint)
|
||||||
for _, candidate := range r.layers {
|
}
|
||||||
if candidate.ID != id {
|
newLayers := []Layer{}
|
||||||
newLayers = append(newLayers, candidate)
|
for _, candidate := range r.layers {
|
||||||
}
|
if candidate.ID != id {
|
||||||
}
|
newLayers = append(newLayers, candidate)
|
||||||
r.layers = newLayers
|
|
||||||
if err = r.Save(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
r.layers = newLayers
|
||||||
|
if err = r.Save(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Lookup(name string) (id string, err error) {
|
func (r *layerStore) Lookup(name string) (id string, err error) {
|
||||||
layer, ok := r.byname[name]
|
if layer, ok := r.lookup(name); ok {
|
||||||
if !ok {
|
return layer.ID, nil
|
||||||
layer, ok = r.byid[name]
|
|
||||||
if !ok {
|
|
||||||
return "", ErrLayerUnknown
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return layer.ID, nil
|
return "", ErrLayerUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Exists(id string) bool {
|
func (r *layerStore) Exists(id string) bool {
|
||||||
if layer, ok := r.byname[id]; ok {
|
_, ok := r.lookup(id)
|
||||||
id = layer.ID
|
return ok
|
||||||
}
|
|
||||||
l, exists := r.byid[id]
|
|
||||||
return l != nil && exists
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Get(id string) (*Layer, error) {
|
func (r *layerStore) Get(id string) (*Layer, error) {
|
||||||
if l, ok := r.byname[id]; ok {
|
if layer, ok := r.lookup(id); ok {
|
||||||
return l, nil
|
return layer, nil
|
||||||
}
|
|
||||||
if l, ok := r.byid[id]; ok {
|
|
||||||
return l, nil
|
|
||||||
}
|
}
|
||||||
return nil, ErrLayerUnknown
|
return nil, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
|
@ -641,22 +619,32 @@ func (r *layerStore) Wipe() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) Changes(from, to string) ([]archive.Change, error) {
|
func (r *layerStore) findParentAndLayer(from, to string) (fromID string, toID string, fromLayer *Layer, toLayer *Layer, err error) {
|
||||||
if layer, ok := r.byname[from]; ok {
|
var ok bool
|
||||||
from = layer.ID
|
toLayer, ok = r.lookup(to)
|
||||||
}
|
if !ok {
|
||||||
if layer, ok := r.byname[to]; ok {
|
return "", "", nil, nil, ErrLayerUnknown
|
||||||
to = layer.ID
|
|
||||||
}
|
}
|
||||||
|
to = toLayer.ID
|
||||||
if from == "" {
|
if from == "" {
|
||||||
if layer, ok := r.byid[to]; ok {
|
from = toLayer.Parent
|
||||||
from = layer.Parent
|
}
|
||||||
|
if from != "" {
|
||||||
|
fromLayer, ok = r.lookup(from)
|
||||||
|
if !ok {
|
||||||
|
fromLayer, ok = r.lookup(toLayer.Parent)
|
||||||
|
if !ok {
|
||||||
|
return "", "", nil, nil, ErrParentUnknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
from = fromLayer.ID
|
||||||
}
|
}
|
||||||
if to == "" {
|
return from, to, fromLayer, toLayer, nil
|
||||||
return nil, ErrLayerUnknown
|
}
|
||||||
}
|
|
||||||
if _, ok := r.byid[to]; !ok {
|
func (r *layerStore) Changes(from, to string) ([]archive.Change, error) {
|
||||||
|
from, to, _, _, err := r.findParentAndLayer(from, to)
|
||||||
|
if err != nil {
|
||||||
return nil, ErrLayerUnknown
|
return nil, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
return r.driver.Changes(to, from)
|
return r.driver.Changes(to, from)
|
||||||
|
@ -694,32 +682,19 @@ func (r *layerStore) newFileGetter(id string) (drivers.FileGetCloser, error) {
|
||||||
func (r *layerStore) Diff(from, to string) (io.ReadCloser, error) {
|
func (r *layerStore) Diff(from, to string) (io.ReadCloser, error) {
|
||||||
var metadata storage.Unpacker
|
var metadata storage.Unpacker
|
||||||
|
|
||||||
if layer, ok := r.byname[from]; ok {
|
from, to, _, toLayer, err := r.findParentAndLayer(from, to)
|
||||||
from = layer.ID
|
if err != nil {
|
||||||
}
|
|
||||||
if layer, ok := r.byname[to]; ok {
|
|
||||||
to = layer.ID
|
|
||||||
}
|
|
||||||
if from == "" {
|
|
||||||
if layer, ok := r.byid[to]; ok {
|
|
||||||
from = layer.Parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if to == "" {
|
|
||||||
return nil, ErrParentUnknown
|
|
||||||
}
|
|
||||||
if _, ok := r.byid[to]; !ok {
|
|
||||||
return nil, ErrLayerUnknown
|
return nil, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
compression := archive.Uncompressed
|
compression := archive.Uncompressed
|
||||||
if cflag, ok := r.byid[to].Flags[compressionFlag]; ok {
|
if cflag, ok := toLayer.Flags[compressionFlag]; ok {
|
||||||
if ctype, ok := cflag.(float64); ok {
|
if ctype, ok := cflag.(float64); ok {
|
||||||
compression = archive.Compression(ctype)
|
compression = archive.Compression(ctype)
|
||||||
} else if ctype, ok := cflag.(archive.Compression); ok {
|
} else if ctype, ok := cflag.(archive.Compression); ok {
|
||||||
compression = archive.Compression(ctype)
|
compression = archive.Compression(ctype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if from != r.byid[to].Parent {
|
if from != toLayer.Parent {
|
||||||
diff, err := r.driver.Diff(to, from)
|
diff, err := r.driver.Diff(to, from)
|
||||||
if err == nil && (compression != archive.Uncompressed) {
|
if err == nil && (compression != archive.Uncompressed) {
|
||||||
preader, pwriter := io.Pipe()
|
preader, pwriter := io.Pipe()
|
||||||
|
@ -797,31 +772,15 @@ func (r *layerStore) Diff(from, to string) (io.ReadCloser, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) DiffSize(from, to string) (size int64, err error) {
|
func (r *layerStore) DiffSize(from, to string) (size int64, err error) {
|
||||||
if layer, ok := r.byname[from]; ok {
|
from, to, _, _, err = r.findParentAndLayer(from, to)
|
||||||
from = layer.ID
|
if err != nil {
|
||||||
}
|
|
||||||
if layer, ok := r.byname[to]; ok {
|
|
||||||
to = layer.ID
|
|
||||||
}
|
|
||||||
if from == "" {
|
|
||||||
if layer, ok := r.byid[to]; ok {
|
|
||||||
from = layer.Parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if to == "" {
|
|
||||||
return -1, ErrParentUnknown
|
|
||||||
}
|
|
||||||
if _, ok := r.byid[to]; !ok {
|
|
||||||
return -1, ErrLayerUnknown
|
return -1, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
return r.driver.DiffSize(to, from)
|
return r.driver.DiffSize(to, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *layerStore) ApplyDiff(to string, diff archive.Reader) (size int64, err error) {
|
func (r *layerStore) ApplyDiff(to string, diff archive.Reader) (size int64, err error) {
|
||||||
if layer, ok := r.byname[to]; ok {
|
layer, ok := r.lookup(to)
|
||||||
to = layer.ID
|
|
||||||
}
|
|
||||||
layer, ok := r.byid[to]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return -1, ErrLayerUnknown
|
return -1, ErrLayerUnknown
|
||||||
}
|
}
|
||||||
|
|
37
vendor/github.com/containers/storage/storage/lockfile.go
generated
vendored
37
vendor/github.com/containers/storage/storage/lockfile.go
generated
vendored
|
@ -4,9 +4,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ func GetLockfile(path string) (Locker, error) {
|
||||||
if locker, ok := lockfiles[filepath.Clean(path)]; ok {
|
if locker, ok := lockfiles[filepath.Clean(path)]; ok {
|
||||||
return locker, nil
|
return locker, nil
|
||||||
}
|
}
|
||||||
fd, err := syscall.Open(filepath.Clean(path), os.O_RDWR|os.O_CREATE, syscall.S_IRUSR|syscall.S_IWUSR)
|
fd, err := unix.Open(filepath.Clean(path), os.O_RDWR|os.O_CREATE, unix.S_IRUSR|unix.S_IWUSR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -61,28 +62,28 @@ func GetLockfile(path string) (Locker, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lockfile) Lock() {
|
func (l *lockfile) Lock() {
|
||||||
lk := syscall.Flock_t{
|
lk := unix.Flock_t{
|
||||||
Type: syscall.F_WRLCK,
|
Type: unix.F_WRLCK,
|
||||||
Whence: int16(os.SEEK_SET),
|
Whence: int16(os.SEEK_SET),
|
||||||
Start: 0,
|
Start: 0,
|
||||||
Len: 0,
|
Len: 0,
|
||||||
Pid: int32(os.Getpid()),
|
Pid: int32(os.Getpid()),
|
||||||
}
|
}
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
for syscall.FcntlFlock(l.fd, syscall.F_SETLKW, &lk) != nil {
|
for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lockfile) Unlock() {
|
func (l *lockfile) Unlock() {
|
||||||
lk := syscall.Flock_t{
|
lk := unix.Flock_t{
|
||||||
Type: syscall.F_UNLCK,
|
Type: unix.F_UNLCK,
|
||||||
Whence: int16(os.SEEK_SET),
|
Whence: int16(os.SEEK_SET),
|
||||||
Start: 0,
|
Start: 0,
|
||||||
Len: 0,
|
Len: 0,
|
||||||
Pid: int32(os.Getpid()),
|
Pid: int32(os.Getpid()),
|
||||||
}
|
}
|
||||||
for syscall.FcntlFlock(l.fd, syscall.F_SETLKW, &lk) != nil {
|
for unix.FcntlFlock(l.fd, unix.F_SETLKW, &lk) != nil {
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
l.mu.Unlock()
|
l.mu.Unlock()
|
||||||
|
@ -91,18 +92,18 @@ func (l *lockfile) Unlock() {
|
||||||
func (l *lockfile) Touch() error {
|
func (l *lockfile) Touch() error {
|
||||||
l.lw = stringid.GenerateRandomID()
|
l.lw = stringid.GenerateRandomID()
|
||||||
id := []byte(l.lw)
|
id := []byte(l.lw)
|
||||||
_, err := syscall.Seek(int(l.fd), 0, os.SEEK_SET)
|
_, err := unix.Seek(int(l.fd), 0, os.SEEK_SET)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
n, err := syscall.Write(int(l.fd), id)
|
n, err := unix.Write(int(l.fd), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if n != len(id) {
|
if n != len(id) {
|
||||||
return syscall.ENOSPC
|
return unix.ENOSPC
|
||||||
}
|
}
|
||||||
err = syscall.Fsync(int(l.fd))
|
err = unix.Fsync(int(l.fd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -111,16 +112,16 @@ func (l *lockfile) Touch() error {
|
||||||
|
|
||||||
func (l *lockfile) Modified() (bool, error) {
|
func (l *lockfile) Modified() (bool, error) {
|
||||||
id := []byte(l.lw)
|
id := []byte(l.lw)
|
||||||
_, err := syscall.Seek(int(l.fd), 0, os.SEEK_SET)
|
_, err := unix.Seek(int(l.fd), 0, os.SEEK_SET)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
n, err := syscall.Read(int(l.fd), id)
|
n, err := unix.Read(int(l.fd), id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
if n != len(id) {
|
if n != len(id) {
|
||||||
return true, syscall.ENOSPC
|
return true, unix.ENOSPC
|
||||||
}
|
}
|
||||||
lw := l.lw
|
lw := l.lw
|
||||||
l.lw = string(id)
|
l.lw = string(id)
|
||||||
|
@ -128,11 +129,11 @@ func (l *lockfile) Modified() (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lockfile) TouchedSince(when time.Time) bool {
|
func (l *lockfile) TouchedSince(when time.Time) bool {
|
||||||
st := syscall.Stat_t{}
|
st := unix.Stat_t{}
|
||||||
err := syscall.Fstat(int(l.fd), &st)
|
err := unix.Fstat(int(l.fd), &st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
touched := time.Unix(st.Mtim.Unix())
|
touched := time.Unix(statTMtimeUnix(st))
|
||||||
return when.Before(touched)
|
return when.Before(touched)
|
||||||
}
|
}
|
||||||
|
|
11
vendor/github.com/containers/storage/storage/stat_mtim.go
generated
vendored
Normal file
11
vendor/github.com/containers/storage/storage/stat_mtim.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build linux solaris
|
||||||
|
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func statTMtimeUnix(st unix.Stat_t) (int64, int64) {
|
||||||
|
return st.Mtim.Unix()
|
||||||
|
}
|
11
vendor/github.com/containers/storage/storage/stat_mtimespec.go
generated
vendored
Normal file
11
vendor/github.com/containers/storage/storage/stat_mtimespec.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build !linux,!solaris
|
||||||
|
|
||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func statTMtimeUnix(st unix.Stat_t) (int64, int64) {
|
||||||
|
return st.Mtimespec.Unix()
|
||||||
|
}
|
11
vendor/github.com/containers/storage/storage/store.go
generated
vendored
11
vendor/github.com/containers/storage/storage/store.go
generated
vendored
|
@ -2176,6 +2176,17 @@ func makeBigDataBaseName(key string) string {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stringSliceWithoutValue(slice []string, value string) []string {
|
||||||
|
modified := []string{}
|
||||||
|
for _, v := range slice {
|
||||||
|
if v == value {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
modified = append(modified, v)
|
||||||
|
}
|
||||||
|
return modified
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
DefaultStoreOptions.RunRoot = "/var/run/containers/storage"
|
DefaultStoreOptions.RunRoot = "/var/run/containers/storage"
|
||||||
DefaultStoreOptions.GraphRoot = "/var/lib/containers/storage"
|
DefaultStoreOptions.GraphRoot = "/var/lib/containers/storage"
|
||||||
|
|
1
vendor/github.com/containers/storage/vendor.conf
generated
vendored
1
vendor/github.com/containers/storage/vendor.conf
generated
vendored
|
@ -10,6 +10,7 @@ github.com/mistifyio/go-zfs c0224de804d438efd11ea6e52ada8014537d6062
|
||||||
github.com/opencontainers/runc 6c22e77604689db8725fa866f0f2ec0b3e8c3a07
|
github.com/opencontainers/runc 6c22e77604689db8725fa866f0f2ec0b3e8c3a07
|
||||||
github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d
|
github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d
|
||||||
github.com/pborman/uuid 1b00554d822231195d1babd97ff4a781231955c9
|
github.com/pborman/uuid 1b00554d822231195d1babd97ff4a781231955c9
|
||||||
|
github.com/tchap/go-patricia v2.2.6
|
||||||
github.com/vbatts/tar-split bd4c5d64c3e9297f410025a3b1bd0c58f659e721
|
github.com/vbatts/tar-split bd4c5d64c3e9297f410025a3b1bd0c58f659e721
|
||||||
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
|
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
|
||||||
golang.org/x/net f2499483f923065a842d38eb4c7f1927e6fc6e6d
|
golang.org/x/net f2499483f923065a842d38eb4c7f1927e6fc6e6d
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue