Vendor in latest containers/storage

This vendor will improve the performance of using userns
since it will save aside the image layer of the chown, so
followup runnings of podman will use the new layer rather
then chowning again.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>

Closes: #881
Approved by: mheon
This commit is contained in:
Daniel J Walsh
2018-06-02 05:34:11 -04:00
committed by Atomic Bot
parent 22e6f11641
commit 13f745092f
18 changed files with 811 additions and 92 deletions

View File

@@ -56,6 +56,11 @@ type (
// replaced with the matching name from this map.
RebaseNames map[string]string
InUserNS bool
// CopyPass indicates that the contents of any archive we're creating
// will instantly be extracted and written to disk, so we can deviate
// from the traditional behavior/format to get features like subsecond
// precision in timestamps.
CopyPass bool
}
)
@@ -396,6 +401,11 @@ type tarAppender struct {
// by the AUFS standard are used as the tar whiteout
// standard.
WhiteoutConverter tarWhiteoutConverter
// CopyPass indicates that the contents of any archive we're creating
// will instantly be extracted and written to disk, so we can deviate
// from the traditional behavior/format to get features like subsecond
// precision in timestamps.
CopyPass bool
}
func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer, chownOpts *idtools.IDPair) *tarAppender {
@@ -446,6 +456,9 @@ func (ta *tarAppender) addTarFile(path, name string) error {
if err := ReadSecurityXattrToTarHeader(path, hdr); err != nil {
return err
}
if ta.CopyPass {
copyPassHeader(hdr)
}
// if it's not a directory and has more than 1 link,
// it's hard linked, so set the type flag accordingly
@@ -710,6 +723,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
options.ChownOpts,
)
ta.WhiteoutConverter = getWhiteoutConverter(options.WhiteoutFormat, options.WhiteoutData)
ta.CopyPass = options.CopyPass
defer func() {
// Make sure to check the error on Close.
@@ -1039,6 +1053,7 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
UIDMaps: tarMappings.UIDs(),
GIDMaps: tarMappings.GIDs(),
Compression: Uncompressed,
CopyPass: true,
}
archive, err := TarWithOptions(src, options)
if err != nil {
@@ -1145,6 +1160,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
}
hdr.Name = filepath.Base(dst)
hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
copyPassHeader(hdr)
if err := remapIDs(archiver.TarIDMappings, nil, archiver.ChownOpts, hdr); err != nil {
return err

View File

@@ -0,0 +1,11 @@
// +build go1.10
package archive
import (
"archive/tar"
)
func copyPassHeader(hdr *tar.Header) {
hdr.Format = tar.FormatPAX
}

View File

@@ -0,0 +1,10 @@
// +build !go1.10
package archive
import (
"archive/tar"
)
func copyPassHeader(hdr *tar.Header) {
}

View File

@@ -1,5 +1,5 @@
// Code generated by ffjson <https://github.com/pquerna/ffjson>. DO NOT EDIT.
// source: ./pkg/archive/archive.go
// source: pkg/archive/archive.go
package archive
@@ -491,6 +491,11 @@ func (j *TarOptions) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
} else {
buf.WriteString(`,"InUserNS":false`)
}
if j.CopyPass {
buf.WriteString(`,"CopyPass":true`)
} else {
buf.WriteString(`,"CopyPass":false`)
}
buf.WriteByte('}')
return nil
}
@@ -524,6 +529,8 @@ const (
ffjtTarOptionsRebaseNames
ffjtTarOptionsInUserNS
ffjtTarOptionsCopyPass
)
var ffjKeyTarOptionsIncludeFiles = []byte("IncludeFiles")
@@ -552,6 +559,8 @@ var ffjKeyTarOptionsRebaseNames = []byte("RebaseNames")
var ffjKeyTarOptionsInUserNS = []byte("InUserNS")
var ffjKeyTarOptionsCopyPass = []byte("CopyPass")
// UnmarshalJSON umarshall json - template of ffjson
func (j *TarOptions) UnmarshalJSON(input []byte) error {
fs := fflib.NewFFLexer(input)
@@ -624,6 +633,11 @@ mainparse:
currentKey = ffjtTarOptionsChownOpts
state = fflib.FFParse_want_colon
goto mainparse
} else if bytes.Equal(ffjKeyTarOptionsCopyPass, kn) {
currentKey = ffjtTarOptionsCopyPass
state = fflib.FFParse_want_colon
goto mainparse
}
case 'E':
@@ -704,6 +718,12 @@ mainparse:
}
if fflib.EqualFoldRight(ffjKeyTarOptionsCopyPass, kn) {
currentKey = ffjtTarOptionsCopyPass
state = fflib.FFParse_want_colon
goto mainparse
}
if fflib.EqualFoldRight(ffjKeyTarOptionsInUserNS, kn) {
currentKey = ffjtTarOptionsInUserNS
state = fflib.FFParse_want_colon
@@ -838,6 +858,9 @@ mainparse:
case ffjtTarOptionsInUserNS:
goto handle_InUserNS
case ffjtTarOptionsCopyPass:
goto handle_CopyPass
case ffjtTarOptionsnosuchkey:
err = fs.SkipField(tok)
if err != nil {
@@ -1481,6 +1504,41 @@ handle_InUserNS:
state = fflib.FFParse_after_value
goto mainparse
handle_CopyPass:
/* handler: j.CopyPass type=bool kind=bool quoted=false*/
{
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
}
}
{
if tok == fflib.FFTok_null {
} else {
tmpb := fs.Output.Bytes()
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
j.CopyPass = true
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
j.CopyPass = false
} else {
err = errors.New("unexpected bytes for true/false value")
return fs.WrapErr(err)
}
}
}
state = fflib.FFParse_after_value
goto mainparse
wantedvalue:
return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
wrongtokenerror:
@@ -1773,6 +1831,11 @@ func (j *tarAppender) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
if err != nil {
return err
}
if j.CopyPass {
buf.WriteString(`,"CopyPass":true`)
} else {
buf.WriteString(`,"CopyPass":false`)
}
buf.WriteByte('}')
return nil
}
@@ -1792,6 +1855,8 @@ const (
ffjttarAppenderChownOpts
ffjttarAppenderWhiteoutConverter
ffjttarAppenderCopyPass
)
var ffjKeytarAppenderTarWriter = []byte("TarWriter")
@@ -1806,6 +1871,8 @@ var ffjKeytarAppenderChownOpts = []byte("ChownOpts")
var ffjKeytarAppenderWhiteoutConverter = []byte("WhiteoutConverter")
var ffjKeytarAppenderCopyPass = []byte("CopyPass")
// UnmarshalJSON umarshall json - template of ffjson
func (j *tarAppender) UnmarshalJSON(input []byte) error {
fs := fflib.NewFFLexer(input)
@@ -1881,6 +1948,11 @@ mainparse:
currentKey = ffjttarAppenderChownOpts
state = fflib.FFParse_want_colon
goto mainparse
} else if bytes.Equal(ffjKeytarAppenderCopyPass, kn) {
currentKey = ffjttarAppenderCopyPass
state = fflib.FFParse_want_colon
goto mainparse
}
case 'I':
@@ -1917,6 +1989,12 @@ mainparse:
}
if fflib.EqualFoldRight(ffjKeytarAppenderCopyPass, kn) {
currentKey = ffjttarAppenderCopyPass
state = fflib.FFParse_want_colon
goto mainparse
}
if fflib.SimpleLetterEqualFold(ffjKeytarAppenderWhiteoutConverter, kn) {
currentKey = ffjttarAppenderWhiteoutConverter
state = fflib.FFParse_want_colon
@@ -1988,6 +2066,9 @@ mainparse:
case ffjttarAppenderWhiteoutConverter:
goto handle_WhiteoutConverter
case ffjttarAppenderCopyPass:
goto handle_CopyPass
case ffjttarAppendernosuchkey:
err = fs.SkipField(tok)
if err != nil {
@@ -2211,6 +2292,41 @@ handle_WhiteoutConverter:
state = fflib.FFParse_after_value
goto mainparse
handle_CopyPass:
/* handler: j.CopyPass type=bool kind=bool quoted=false*/
{
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
}
}
{
if tok == fflib.FFTok_null {
} else {
tmpb := fs.Output.Bytes()
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
j.CopyPass = true
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
j.CopyPass = false
} else {
err = errors.New("unexpected bytes for true/false value")
return fs.WrapErr(err)
}
}
}
state = fflib.FFParse_after_value
goto mainparse
wantedvalue:
return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
wrongtokenerror:

View File

@@ -0,0 +1 @@
This package provides helper functions for dealing with strings

View File

@@ -0,0 +1,99 @@
// Package stringutils provides helper functions for dealing with strings.
package stringutils
import (
"bytes"
"math/rand"
"strings"
)
// GenerateRandomAlphaOnlyString generates an alphabetical random string with length n.
func GenerateRandomAlphaOnlyString(n int) string {
// make a really long string
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]byte, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
// GenerateRandomASCIIString generates an ASCII random string with length n.
func GenerateRandomASCIIString(n int) string {
chars := "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"~!@#$%^&*()-_+={}[]\\|<,>.?/\"';:` "
res := make([]byte, n)
for i := 0; i < n; i++ {
res[i] = chars[rand.Intn(len(chars))]
}
return string(res)
}
// Ellipsis truncates a string to fit within maxlen, and appends ellipsis (...).
// For maxlen of 3 and lower, no ellipsis is appended.
func Ellipsis(s string, maxlen int) string {
r := []rune(s)
if len(r) <= maxlen {
return s
}
if maxlen <= 3 {
return string(r[:maxlen])
}
return string(r[:maxlen-3]) + "..."
}
// Truncate truncates a string to maxlen.
func Truncate(s string, maxlen int) string {
r := []rune(s)
if len(r) <= maxlen {
return s
}
return string(r[:maxlen])
}
// InSlice tests whether a string is contained in a slice of strings or not.
// Comparison is case insensitive
func InSlice(slice []string, s string) bool {
for _, ss := range slice {
if strings.ToLower(s) == strings.ToLower(ss) {
return true
}
}
return false
}
func quote(word string, buf *bytes.Buffer) {
// Bail out early for "simple" strings
if word != "" && !strings.ContainsAny(word, "\\'\"`${[|&;<>()~*?! \t\n") {
buf.WriteString(word)
return
}
buf.WriteString("'")
for i := 0; i < len(word); i++ {
b := word[i]
if b == '\'' {
// Replace literal ' with a close ', a \', and an open '
buf.WriteString("'\\''")
} else {
buf.WriteByte(b)
}
}
buf.WriteString("'")
}
// ShellQuoteArguments takes a list of strings and escapes them so they will be
// handled right when passed as arguments to a program via a shell
func ShellQuoteArguments(args []string) string {
var buf bytes.Buffer
for i, arg := range args {
if i != 0 {
buf.WriteByte(' ')
}
quote(arg, &buf)
}
return buf.String()
}

View File

@@ -28,6 +28,20 @@ func (s StatT) Mtim() time.Time {
return time.Time(s.mtim)
}
// UID returns file's user id of owner.
//
// on windows this is always 0 because there is no concept of UID
func (s StatT) UID() uint32 {
return 0
}
// GID returns file's group id of owner.
//
// on windows this is always 0 because there is no concept of GID
func (s StatT) GID() uint32 {
return 0
}
// Stat takes a path to a file and returns
// a system.StatT type pertaining to that file.
//