Upgrade dependency to go-containerregistry third-party library

By doing so it will fix issues met when mixing source/remote registry

Close #808
This commit is contained in:
Ben Einaudi
2020-01-26 18:55:52 +01:00
parent e8fffda7cb
commit 03b8922ede
1160 changed files with 107253 additions and 38471 deletions
+66
View File
@@ -0,0 +1,66 @@
# This file lists all individuals having contributed content to the repository.
# For how it is generated, see `scripts/generate-authors.sh`.
Aaron L. Xu <likexu@harmonycloud.cn>
Aaron Lehmann <aaron.lehmann@docker.com>
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Alexander Morozov <lk4d4@docker.com>
Alice Frosi <afrosi@de.ibm.com>
Allen Sun <allen.sun@daocloud.io>
Anda Xu <anda.xu@docker.com>
Anthony Sottile <asottile@umich.edu>
Arnaud Bailly <arnaud.oqube@gmail.com>
Bin Liu <liubin0329@gmail.com>
Brian Goff <cpuguy83@gmail.com>
Daniel Nephin <dnephin@gmail.com>
Dave Chen <dave.chen@arm.com>
David Calavera <david.calavera@gmail.com>
Dennis Chen <dennis.chen@arm.com>
Derek McGowan <derek@mcgstyle.net>
Doug Davis <dug@us.ibm.com>
Edgar Lee <edgarl@netflix.com>
Eli Uriegas <eli.uriegas@docker.com>
f0 <f0@users.noreply.github.com>
Fernando Miguel <github@FernandoMiguel.net>
Hao Hu <hao.hu.fr@gmail.com>
Helen Xie <chenjg@harmonycloud.cn>
Himanshu Pandey <hpandey@pivotal.io>
Hiromu Nakamura <abctail30@gmail.com>
Ian Campbell <ijc@docker.com>
Iskander (Alex) Sharipov <quasilyte@gmail.com>
Jean-Pierre Huynh <jean-pierre.huynh@ounet.fr>
Jessica Frazelle <acidburn@microsoft.com>
John Howard <jhoward@microsoft.com>
Jonathan Stoppani <jonathan.stoppani@divio.com>
Justas Brazauskas <brazauskasjustas@gmail.com>
Justin Cormack <justin.cormack@docker.com>
Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>
Lajos Papp <lalyos@yahoo.com>
Matt Rickard <mrick@google.com>
Michael Crosby <crosbymichael@gmail.com>
Miyachi Katsuya <miyachi_katsuya@r.recruit.co.jp>
Nao YONASHIRO <yonashiro@r.recruit.co.jp>
Natasha Jarus <linuxmercedes@gmail.com>
Noel Georgi <18496730+frezbo@users.noreply.github.com>
Ondrej Fabry <ofabry@cisco.com>
Patrick Van Stee <patrick@vanstee.me>
Ri Xu <xuri.me@gmail.com>
Sebastiaan van Stijn <github@gone.nl>
Shev Yan <yandong_8212@163.com>
Simon Ferquel <simon.ferquel@docker.com>
Stefan Weil <sw@weilnetz.de>
Thomas Leonard <thomas.leonard@docker.com>
Thomas Shaw <tomwillfixit@users.noreply.github.com>
Tibor Vass <tibor@docker.com>
Tiffany Jernigan <tiffany.f.j@gmail.com>
Tino Rusch <tino.rusch@gmail.com>
Tobias Klauser <tklauser@distanz.ch>
Tomas Tomecek <ttomecek@redhat.com>
Tomohiro Kusumoto <zabio1192@gmail.com>
Tõnis Tiigi <tonistiigi@gmail.com>
Vincent Demeester <vincent.demeester@docker.com>
Wei Fu <fuweid89@gmail.com>
Yong Tang <yong.tang.github@outlook.com>
Yuichiro Kaneko <spiketeika@gmail.com>
Ziv Tsarfati <digger18@gmail.com>
郑泽宇 <perhapszzy@sina.com>
@@ -200,6 +200,11 @@ type CopyCommand struct {
// Expand variables
func (c *CopyCommand) Expand(expander SingleWordExpander) error {
expandedChown, err := expander(c.Chown)
if err != nil {
return err
}
c.Chown = expandedChown
return expandSliceInPlace(c.SourcesAndDest, expander)
}
@@ -0,0 +1,7 @@
// +build !dfsecrets
package instructions
func isSecretMountsSupported() bool {
return false
}
@@ -0,0 +1,7 @@
// +build !dfssh
package instructions
func isSSHMountsSupported() bool {
return false
}
@@ -1,4 +1,4 @@
// +build dfrunmount dfextall
// +build dfrunmount
package instructions
@@ -13,11 +13,15 @@ import (
const MountTypeBind = "bind"
const MountTypeCache = "cache"
const MountTypeTmpfs = "tmpfs"
const MountTypeSecret = "secret"
const MountTypeSSH = "ssh"
var allowedMountTypes = map[string]struct{}{
MountTypeBind: {},
MountTypeCache: {},
MountTypeTmpfs: {},
MountTypeBind: {},
MountTypeCache: {},
MountTypeTmpfs: {},
MountTypeSecret: {},
MountTypeSSH: {},
}
const MountSharingShared = "shared"
@@ -40,6 +44,16 @@ func init() {
}
func isValidMountType(s string) bool {
if s == "secret" {
if !isSecretMountsSupported() {
return false
}
}
if s == "ssh" {
if !isSSHMountsSupported() {
return false
}
}
_, ok := allowedMountTypes[s]
return ok
}
@@ -93,6 +107,10 @@ type Mount struct {
ReadOnly bool
CacheID string
CacheSharing string
Required bool
Mode *uint64
UID *uint64
GID *uint64
}
func parseMount(value string) (*Mount, error) {
@@ -120,6 +138,13 @@ func parseMount(value string) (*Mount, error) {
m.ReadOnly = false
roAuto = false
continue
case "required":
if m.Type == "secret" || m.Type == "ssh" {
m.Required = true
continue
} else {
return nil, errors.Errorf("unexpected key '%s' for mount type '%s'", key, m.Type)
}
}
}
@@ -153,6 +178,16 @@ func parseMount(value string) (*Mount, error) {
}
m.ReadOnly = !rw
roAuto = false
case "required":
if m.Type == "secret" || m.Type == "ssh" {
v, err := strconv.ParseBool(value)
if err != nil {
return nil, errors.Errorf("invalid value for %s: %s", key, value)
}
m.Required = v
} else {
return nil, errors.Errorf("unexpected key '%s' for mount type '%s'", key, m.Type)
}
case "id":
m.CacheID = value
case "sharing":
@@ -160,13 +195,45 @@ func parseMount(value string) (*Mount, error) {
return nil, errors.Errorf("unsupported sharing value %q", value)
}
m.CacheSharing = strings.ToLower(value)
case "mode":
mode, err := strconv.ParseUint(value, 8, 32)
if err != nil {
return nil, errors.Errorf("invalid value %s for mode", value)
}
m.Mode = &mode
case "uid":
uid, err := strconv.ParseUint(value, 10, 32)
if err != nil {
return nil, errors.Errorf("invalid value %s for uid", value)
}
m.UID = &uid
case "gid":
gid, err := strconv.ParseUint(value, 10, 32)
if err != nil {
return nil, errors.Errorf("invalid value %s for gid", value)
}
m.GID = &gid
default:
return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field)
}
}
fileInfoAllowed := m.Type == MountTypeSecret || m.Type == MountTypeSSH || m.Type == MountTypeCache
if m.Mode != nil && !fileInfoAllowed {
return nil, errors.Errorf("mode not allowed for %q type mounts", m.Type)
}
if m.UID != nil && !fileInfoAllowed {
return nil, errors.Errorf("uid not allowed for %q type mounts", m.Type)
}
if m.GID != nil && !fileInfoAllowed {
return nil, errors.Errorf("gid not allowed for %q type mounts", m.Type)
}
if roAuto {
if m.Type == MountTypeCache {
if m.Type == MountTypeCache || m.Type == MountTypeTmpfs {
m.ReadOnly = false
} else {
m.ReadOnly = true
@@ -177,5 +244,20 @@ func parseMount(value string) (*Mount, error) {
return nil, errors.Errorf("invalid cache sharing set for %v mount", m.Type)
}
if m.Type == MountTypeSecret {
if m.From != "" {
return nil, errors.Errorf("secret mount should not have a from")
}
if m.CacheSharing != "" {
return nil, errors.Errorf("secret mount should not define sharing")
}
if m.Source == "" && m.Target == "" && m.CacheID == "" {
return nil, errors.Errorf("invalid secret mount. one of source, target required")
}
if m.Source != "" && m.CacheID != "" {
return nil, errors.Errorf("both source and id can't be set")
}
}
return m, nil
}
@@ -0,0 +1,63 @@
// +build dfrunnetwork
package instructions
import (
"github.com/pkg/errors"
)
const (
NetworkDefault = "default"
NetworkNone = "none"
NetworkHost = "host"
)
var allowedNetwork = map[string]struct{}{
NetworkDefault: {},
NetworkNone: {},
NetworkHost: {},
}
func isValidNetwork(value string) bool {
_, ok := allowedNetwork[value]
return ok
}
var networkKey = "dockerfile/run/network"
func init() {
parseRunPreHooks = append(parseRunPreHooks, runNetworkPreHook)
parseRunPostHooks = append(parseRunPostHooks, runNetworkPostHook)
}
func runNetworkPreHook(cmd *RunCommand, req parseRequest) error {
st := &networkState{}
st.flag = req.flags.AddString("network", NetworkDefault)
cmd.setExternalValue(networkKey, st)
return nil
}
func runNetworkPostHook(cmd *RunCommand, req parseRequest) error {
st := cmd.getExternalValue(networkKey).(*networkState)
if st == nil {
return errors.Errorf("no network state")
}
value := st.flag.Value
if !isValidNetwork(value) {
return errors.Errorf("invalid network mode %q", value)
}
st.networkMode = value
return nil
}
func GetNetwork(cmd *RunCommand) string {
return cmd.getExternalValue(networkKey).(*networkState).networkMode
}
type networkState struct {
flag *Flag
networkMode string
}
@@ -0,0 +1,61 @@
// +build dfrunsecurity
package instructions
import (
"github.com/pkg/errors"
)
const (
SecurityInsecure = "insecure"
SecuritySandbox = "sandbox"
)
var allowedSecurity = map[string]struct{}{
SecurityInsecure: {},
SecuritySandbox: {},
}
func isValidSecurity(value string) bool {
_, ok := allowedSecurity[value]
return ok
}
var securityKey = "dockerfile/run/security"
func init() {
parseRunPreHooks = append(parseRunPreHooks, runSecurityPreHook)
parseRunPostHooks = append(parseRunPostHooks, runSecurityPostHook)
}
func runSecurityPreHook(cmd *RunCommand, req parseRequest) error {
st := &securityState{}
st.flag = req.flags.AddString("security", SecuritySandbox)
cmd.setExternalValue(securityKey, st)
return nil
}
func runSecurityPostHook(cmd *RunCommand, req parseRequest) error {
st := cmd.getExternalValue(securityKey).(*securityState)
if st == nil {
return errors.Errorf("no security state")
}
value := st.flag.Value
if !isValidSecurity(value) {
return errors.Errorf("security %q is not valid", value)
}
st.security = value
return nil
}
func GetSecurity(cmd *RunCommand) string {
return cmd.getExternalValue(securityKey).(*securityState).security
}
type securityState struct {
flag *Flag
security string
}
@@ -0,0 +1,7 @@
// +build dfsecrets
package instructions
func isSecretMountsSupported() bool {
return true
}
@@ -0,0 +1,7 @@
// +build dfssh
package instructions
func isSSHMountsSupported() bool {
return true
}
+8 -3
View File
@@ -35,7 +35,7 @@ type Node struct {
Original string // original line used before parsing
Flags []string // only top Node should have this set
StartLine int // the line in the original dockerfile where the node begins
endLine int // the line in the original dockerfile where the node ends
EndLine int // the line in the original dockerfile where the node ends
}
// Dump dumps the AST defined by `node` as a list of sexps.
@@ -65,7 +65,7 @@ func (node *Node) Dump() string {
func (node *Node) lines(start, end int) {
node.StartLine = start
node.endLine = end
node.EndLine = end
}
// AddChild adds a new child node, and updates line information
@@ -74,7 +74,7 @@ func (node *Node) AddChild(child *Node, startLine, endLine int) {
if node.StartLine < 0 {
node.StartLine = startLine
}
node.endLine = endLine
node.EndLine = endLine
node.Children = append(node.Children, child)
}
@@ -275,6 +275,11 @@ func Parse(rwc io.Reader) (*Result, error) {
if len(warnings) > 0 {
warnings = append(warnings, "[WARNING]: Empty continuation lines will become errors in a future release.")
}
if root.StartLine < 0 {
return nil, errors.New("file with no instructions.")
}
return &Result{
AST: root,
Warnings: warnings,
+53 -24
View File
@@ -2,6 +2,7 @@ package shell
import (
"bytes"
"fmt"
"strings"
"text/scanner"
"unicode"
@@ -17,7 +18,9 @@ import (
// It doesn't support all flavors of ${xx:...} formats but new ones can
// be added by adding code to the "special ${} format processing" section
type Lex struct {
escapeToken rune
escapeToken rune
RawQuotes bool
SkipUnsetEnv bool
}
// NewLex creates a new Lex which uses escapeToken to escape quotes.
@@ -58,17 +61,21 @@ func (s *Lex) ProcessWordsWithMap(word string, env map[string]string) ([]string,
func (s *Lex) process(word string, env map[string]string) (string, []string, error) {
sw := &shellWord{
envs: env,
escapeToken: s.escapeToken,
envs: env,
escapeToken: s.escapeToken,
skipUnsetEnv: s.SkipUnsetEnv,
rawQuotes: s.RawQuotes,
}
sw.scanner.Init(strings.NewReader(word))
return sw.process(word)
}
type shellWord struct {
scanner scanner.Scanner
envs map[string]string
escapeToken rune
scanner scanner.Scanner
envs map[string]string
escapeToken rune
rawQuotes bool
skipUnsetEnv bool
}
func (sw *shellWord) process(source string) (string, []string, error) {
@@ -103,10 +110,8 @@ func (w *wordsStruct) addRawChar(ch rune) {
}
func (w *wordsStruct) addString(str string) {
var scan scanner.Scanner
scan.Init(strings.NewReader(str))
for scan.Peek() != scanner.EOF {
w.addChar(scan.Next())
for _, ch := range str {
w.addChar(ch)
}
}
@@ -196,14 +201,20 @@ func (sw *shellWord) processSingleQuote() (string, error) {
var result bytes.Buffer
sw.scanner.Next()
ch := sw.scanner.Next()
if sw.rawQuotes {
result.WriteRune(ch)
}
for {
ch := sw.scanner.Next()
ch = sw.scanner.Next()
switch ch {
case scanner.EOF:
return "", errors.New("unexpected end of statement while looking for matching single-quote")
case '\'':
if sw.rawQuotes {
result.WriteRune(ch)
}
return result.String(), nil
}
result.WriteRune(ch)
@@ -225,14 +236,20 @@ func (sw *shellWord) processDoubleQuote() (string, error) {
var result bytes.Buffer
sw.scanner.Next()
ch := sw.scanner.Next()
if sw.rawQuotes {
result.WriteRune(ch)
}
for {
switch sw.scanner.Peek() {
case scanner.EOF:
return "", errors.New("unexpected end of statement while looking for matching double-quote")
case '"':
sw.scanner.Next()
ch := sw.scanner.Next()
if sw.rawQuotes {
result.WriteRune(ch)
}
return result.String(), nil
case '$':
value, err := sw.processDollar()
@@ -269,7 +286,11 @@ func (sw *shellWord) processDollar() (string, error) {
if name == "" {
return "$", nil
}
return sw.getEnv(name), nil
value, found := sw.getEnv(name)
if !found && sw.skipUnsetEnv {
return "$" + name, nil
}
return value, nil
}
sw.scanner.Next()
@@ -285,7 +306,11 @@ func (sw *shellWord) processDollar() (string, error) {
switch ch {
case '}':
// Normal ${xx} case
return sw.getEnv(name), nil
value, found := sw.getEnv(name)
if !found && sw.skipUnsetEnv {
return fmt.Sprintf("${%s}", name), nil
}
return value, nil
case ':':
// Special ${xx:...} format processing
// Yes it allows for recursive $'s in the ... spot
@@ -301,19 +326,26 @@ func (sw *shellWord) processDollar() (string, error) {
// Grab the current value of the variable in question so we
// can use to to determine what to do based on the modifier
newValue := sw.getEnv(name)
newValue, found := sw.getEnv(name)
switch modifier {
case '+':
if newValue != "" {
newValue = word
}
if !found && sw.skipUnsetEnv {
return fmt.Sprintf("${%s:%s%s}", name, string(modifier), word), nil
}
return newValue, nil
case '-':
if newValue == "" {
newValue = word
}
if !found && sw.skipUnsetEnv {
return fmt.Sprintf("${%s:%s%s}", name, string(modifier), word), nil
}
return newValue, nil
default:
@@ -364,13 +396,13 @@ func isSpecialParam(char rune) bool {
return false
}
func (sw *shellWord) getEnv(name string) string {
func (sw *shellWord) getEnv(name string) (string, bool) {
for key, value := range sw.envs {
if EqualEnvKeys(name, key) {
return value
return value, true
}
}
return ""
return "", false
}
func BuildEnvs(env []string) map[string]string {
@@ -385,10 +417,7 @@ func BuildEnvs(env []string) map[string]string {
k := e[:i]
v := e[i+1:]
// If key already exists, keep previous value.
if _, ok := envs[k]; ok {
continue
}
// overwrite value if key already exists
envs[k] = v
}
}
+23 -15
View File
@@ -9,11 +9,12 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/tonistiigi/fsutil"
fstypes "github.com/tonistiigi/fsutil/types"
"google.golang.org/grpc"
)
func sendDiffCopy(stream grpc.Stream, fs fsutil.FS, progress progressCb) error {
return fsutil.Send(stream.Context(), stream, fs, progress)
return errors.WithStack(fsutil.Send(stream.Context(), stream, fs, progress))
}
func newStreamWriter(stream grpc.ClientStream) io.WriteCloser {
@@ -28,7 +29,7 @@ type bufferedWriteCloser struct {
func (bwc *bufferedWriteCloser) Close() error {
if err := bwc.Writer.Flush(); err != nil {
return err
return errors.WithStack(err)
}
return bwc.Closer.Close()
}
@@ -39,24 +40,30 @@ type streamWriterCloser struct {
func (wc *streamWriterCloser) Write(dt []byte) (int, error) {
if err := wc.ClientStream.SendMsg(&BytesMessage{Data: dt}); err != nil {
return 0, err
// SendMsg return EOF on remote errors
if errors.Cause(err) == io.EOF {
if err := errors.WithStack(wc.ClientStream.RecvMsg(struct{}{})); err != nil {
return 0, err
}
}
return 0, errors.WithStack(err)
}
return len(dt), nil
}
func (wc *streamWriterCloser) Close() error {
if err := wc.ClientStream.CloseSend(); err != nil {
return err
return errors.WithStack(err)
}
// block until receiver is done
var bm BytesMessage
if err := wc.ClientStream.RecvMsg(&bm); err != io.EOF {
return err
return errors.WithStack(err)
}
return nil
}
func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progressCb) error {
func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progressCb, filter func(string, *fstypes.Stat) bool) error {
st := time.Now()
defer func() {
logrus.Debugf("diffcopy took: %v", time.Since(st))
@@ -68,29 +75,30 @@ func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progres
cf = cu.HandleChange
ch = cu.ContentHasher()
}
return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
return errors.WithStack(fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
NotifyHashed: cf,
ContentHasher: ch,
ProgressCb: progress,
})
Filter: fsutil.FilterFunc(filter),
}))
}
func syncTargetDiffCopy(ds grpc.Stream, dest string) error {
if err := os.MkdirAll(dest, 0700); err != nil {
return err
return errors.Wrapf(err, "failed to create synctarget dest dir %s", dest)
}
return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
return errors.WithStack(fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
Merge: true,
Filter: func() func(*fsutil.Stat) bool {
Filter: func() func(string, *fstypes.Stat) bool {
uid := os.Getuid()
gid := os.Getgid()
return func(st *fsutil.Stat) bool {
return func(p string, st *fstypes.Stat) bool {
st.Uid = uint32(uid)
st.Gid = uint32(gid)
return true
}
}(),
})
}))
}
func writeTargetFile(ds grpc.Stream, wc io.WriteCloser) error {
@@ -100,10 +108,10 @@ func writeTargetFile(ds grpc.Stream, wc io.WriteCloser) error {
if errors.Cause(err) == io.EOF {
return nil
}
return err
return errors.WithStack(err)
}
if _, err := wc.Write(bm.Data); err != nil {
return err
return errors.WithStack(err)
}
}
}
+43 -18
View File
@@ -10,6 +10,7 @@ import (
"github.com/moby/buildkit/session"
"github.com/pkg/errors"
"github.com/tonistiigi/fsutil"
fstypes "github.com/tonistiigi/fsutil/types"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
@@ -17,11 +18,12 @@ import (
)
const (
keyOverrideExcludes = "override-excludes"
keyIncludePatterns = "include-patterns"
keyExcludePatterns = "exclude-patterns"
keyFollowPaths = "followpaths"
keyDirName = "dir-name"
keyOverrideExcludes = "override-excludes"
keyIncludePatterns = "include-patterns"
keyExcludePatterns = "exclude-patterns"
keyFollowPaths = "followpaths"
keyDirName = "dir-name"
keyExporterMetaPrefix = "exporter-md-"
)
type fsSyncProvider struct {
@@ -34,7 +36,7 @@ type SyncedDir struct {
Name string
Dir string
Excludes []string
Map func(*fsutil.Stat) bool
Map func(string, *fstypes.Stat) bool
}
// NewFSSyncProvider creates a new provider for sending files from client
@@ -128,7 +130,7 @@ type progressCb func(int, bool)
type protocol struct {
name string
sendFn func(stream grpc.Stream, fs fsutil.FS, progress progressCb) error
recvFn func(stream grpc.Stream, destDir string, cu CacheUpdater, progress progressCb) error
recvFn func(stream grpc.Stream, destDir string, cu CacheUpdater, progress progressCb, mapFunc func(string, *fstypes.Stat) bool) error
}
func isProtoSupported(p string) bool {
@@ -157,6 +159,7 @@ type FSSendRequestOpt struct {
DestDir string
CacheUpdater CacheUpdater
ProgressCb func(int, bool)
Filter func(string, *fstypes.Stat) bool
}
// CacheUpdater is an object capable of sending notifications for the cache hash changes
@@ -224,7 +227,7 @@ func FSSync(ctx context.Context, c session.Caller, opt FSSendRequestOpt) error {
panic(fmt.Sprintf("invalid protocol: %q", pr.name))
}
return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb)
return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb, opt.Filter)
}
// NewFSSyncTargetDir allows writing into a directory
@@ -236,16 +239,16 @@ func NewFSSyncTargetDir(outdir string) session.Attachable {
}
// NewFSSyncTarget allows writing into an io.WriteCloser
func NewFSSyncTarget(w io.WriteCloser) session.Attachable {
func NewFSSyncTarget(f func(map[string]string) (io.WriteCloser, error)) session.Attachable {
p := &fsSyncTarget{
outfile: w,
f: f,
}
return p
}
type fsSyncTarget struct {
outdir string
outfile io.WriteCloser
outdir string
f func(map[string]string) (io.WriteCloser, error)
}
func (sp *fsSyncTarget) Register(server *grpc.Server) {
@@ -256,11 +259,26 @@ func (sp *fsSyncTarget) DiffCopy(stream FileSend_DiffCopyServer) error {
if sp.outdir != "" {
return syncTargetDiffCopy(stream, sp.outdir)
}
if sp.outfile == nil {
if sp.f == nil {
return errors.New("empty outfile and outdir")
}
defer sp.outfile.Close()
return writeTargetFile(stream, sp.outfile)
opts, _ := metadata.FromIncomingContext(stream.Context()) // if no metadata continue with empty object
md := map[string]string{}
for k, v := range opts {
if strings.HasPrefix(k, keyExporterMetaPrefix) {
md[strings.TrimPrefix(k, keyExporterMetaPrefix)] = strings.Join(v, ",")
}
}
wc, err := sp.f(md)
if err != nil {
return err
}
if wc == nil {
return status.Errorf(codes.AlreadyExists, "target already exists")
}
defer wc.Close()
return writeTargetFile(stream, wc)
}
func CopyToCaller(ctx context.Context, fs fsutil.FS, c session.Caller, progress func(int, bool)) error {
@@ -273,13 +291,13 @@ func CopyToCaller(ctx context.Context, fs fsutil.FS, c session.Caller, progress
cc, err := client.DiffCopy(ctx)
if err != nil {
return err
return errors.WithStack(err)
}
return sendDiffCopy(cc, fs, progress)
}
func CopyFileWriter(ctx context.Context, c session.Caller) (io.WriteCloser, error) {
func CopyFileWriter(ctx context.Context, md map[string]string, c session.Caller) (io.WriteCloser, error) {
method := session.MethodURL(_FileSend_serviceDesc.ServiceName, "diffcopy")
if !c.Supports(method) {
return nil, errors.Errorf("method %s not supported by the client", method)
@@ -287,9 +305,16 @@ func CopyFileWriter(ctx context.Context, c session.Caller) (io.WriteCloser, erro
client := NewFileSendClient(c.Conn())
opts := make(map[string][]string, len(md))
for k, v := range md {
opts[keyExporterMetaPrefix+k] = []string{v}
}
ctx = metadata.NewOutgoingContext(ctx, opts)
cc, err := client.DiffCopy(ctx)
if err != nil {
return nil, err
return nil, errors.WithStack(err)
}
return newStreamWriter(cc), nil
+56 -31
View File
@@ -1,15 +1,6 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: filesync.proto
/*
Package filesync is a generated protocol buffer package.
It is generated from these files:
filesync.proto
It has these top-level messages:
BytesMessage
*/
package filesync
import proto "github.com/gogo/protobuf/proto"
@@ -21,8 +12,10 @@ import bytes "bytes"
import strings "strings"
import reflect "reflect"
import context "golang.org/x/net/context"
import grpc "google.golang.org/grpc"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
import io "io"
@@ -42,9 +35,37 @@ type BytesMessage struct {
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}
func (m *BytesMessage) Reset() { *m = BytesMessage{} }
func (*BytesMessage) ProtoMessage() {}
func (*BytesMessage) Descriptor() ([]byte, []int) { return fileDescriptorFilesync, []int{0} }
func (m *BytesMessage) Reset() { *m = BytesMessage{} }
func (*BytesMessage) ProtoMessage() {}
func (*BytesMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_filesync_26f8b7bce2e5ac0e, []int{0}
}
func (m *BytesMessage) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *BytesMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_BytesMessage.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalTo(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (dst *BytesMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_BytesMessage.Merge(dst, src)
}
func (m *BytesMessage) XXX_Size() int {
return m.Size()
}
func (m *BytesMessage) XXX_DiscardUnknown() {
xxx_messageInfo_BytesMessage.DiscardUnknown(m)
}
var xxx_messageInfo_BytesMessage proto.InternalMessageInfo
func (m *BytesMessage) GetData() []byte {
if m != nil {
@@ -107,8 +128,9 @@ var _ grpc.ClientConn
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for FileSync service
// FileSyncClient is the client API for FileSync service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type FileSyncClient interface {
DiffCopy(ctx context.Context, opts ...grpc.CallOption) (FileSync_DiffCopyClient, error)
TarStream(ctx context.Context, opts ...grpc.CallOption) (FileSync_TarStreamClient, error)
@@ -123,7 +145,7 @@ func NewFileSyncClient(cc *grpc.ClientConn) FileSyncClient {
}
func (c *fileSyncClient) DiffCopy(ctx context.Context, opts ...grpc.CallOption) (FileSync_DiffCopyClient, error) {
stream, err := grpc.NewClientStream(ctx, &_FileSync_serviceDesc.Streams[0], c.cc, "/moby.filesync.v1.FileSync/DiffCopy", opts...)
stream, err := c.cc.NewStream(ctx, &_FileSync_serviceDesc.Streams[0], "/moby.filesync.v1.FileSync/DiffCopy", opts...)
if err != nil {
return nil, err
}
@@ -154,7 +176,7 @@ func (x *fileSyncDiffCopyClient) Recv() (*BytesMessage, error) {
}
func (c *fileSyncClient) TarStream(ctx context.Context, opts ...grpc.CallOption) (FileSync_TarStreamClient, error) {
stream, err := grpc.NewClientStream(ctx, &_FileSync_serviceDesc.Streams[1], c.cc, "/moby.filesync.v1.FileSync/TarStream", opts...)
stream, err := c.cc.NewStream(ctx, &_FileSync_serviceDesc.Streams[1], "/moby.filesync.v1.FileSync/TarStream", opts...)
if err != nil {
return nil, err
}
@@ -184,8 +206,7 @@ func (x *fileSyncTarStreamClient) Recv() (*BytesMessage, error) {
return m, nil
}
// Server API for FileSync service
// FileSyncServer is the server API for FileSync service.
type FileSyncServer interface {
DiffCopy(FileSync_DiffCopyServer) error
TarStream(FileSync_TarStreamServer) error
@@ -268,8 +289,9 @@ var _FileSync_serviceDesc = grpc.ServiceDesc{
Metadata: "filesync.proto",
}
// Client API for FileSend service
// FileSendClient is the client API for FileSend service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type FileSendClient interface {
DiffCopy(ctx context.Context, opts ...grpc.CallOption) (FileSend_DiffCopyClient, error)
}
@@ -283,7 +305,7 @@ func NewFileSendClient(cc *grpc.ClientConn) FileSendClient {
}
func (c *fileSendClient) DiffCopy(ctx context.Context, opts ...grpc.CallOption) (FileSend_DiffCopyClient, error) {
stream, err := grpc.NewClientStream(ctx, &_FileSend_serviceDesc.Streams[0], c.cc, "/moby.filesync.v1.FileSend/DiffCopy", opts...)
stream, err := c.cc.NewStream(ctx, &_FileSend_serviceDesc.Streams[0], "/moby.filesync.v1.FileSend/DiffCopy", opts...)
if err != nil {
return nil, err
}
@@ -313,8 +335,7 @@ func (x *fileSendDiffCopyClient) Recv() (*BytesMessage, error) {
return m, nil
}
// Server API for FileSend service
// FileSendServer is the server API for FileSend service.
type FileSendServer interface {
DiffCopy(FileSend_DiffCopyServer) error
}
@@ -398,6 +419,9 @@ func encodeVarintFilesync(dAtA []byte, offset int, v uint64) int {
return offset + 1
}
func (m *BytesMessage) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Data)
@@ -624,10 +648,10 @@ var (
ErrIntOverflowFilesync = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("filesync.proto", fileDescriptorFilesync) }
func init() { proto.RegisterFile("filesync.proto", fileDescriptor_filesync_26f8b7bce2e5ac0e) }
var fileDescriptorFilesync = []byte{
// 208 bytes of a gzipped FileDescriptorProto
var fileDescriptor_filesync_26f8b7bce2e5ac0e = []byte{
// 217 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0xcb, 0xcc, 0x49,
0x2d, 0xae, 0xcc, 0x4b, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xc8, 0xcd, 0x4f, 0xaa,
0xd4, 0x83, 0x0b, 0x96, 0x19, 0x2a, 0x29, 0x71, 0xf1, 0x38, 0x55, 0x96, 0xa4, 0x16, 0xfb, 0xa6,
@@ -636,9 +660,10 @@ var fileDescriptorFilesync = []byte{
0x2b, 0xf3, 0x92, 0x85, 0xfc, 0xb8, 0x38, 0x5c, 0x32, 0xd3, 0xd2, 0x9c, 0xf3, 0x0b, 0x2a, 0x85,
0xe4, 0xf4, 0xd0, 0xcd, 0xd3, 0x43, 0x36, 0x4c, 0x8a, 0x80, 0xbc, 0x06, 0xa3, 0x01, 0xa3, 0x90,
0x3f, 0x17, 0x67, 0x48, 0x62, 0x51, 0x70, 0x49, 0x51, 0x6a, 0x62, 0x2e, 0x35, 0x0c, 0x34, 0x8a,
0x82, 0x3a, 0x36, 0x35, 0x2f, 0x85, 0xda, 0x8e, 0x75, 0x32, 0xbb, 0xf0, 0x50, 0x8e, 0xe1, 0xc6,
0x82, 0x3a, 0x36, 0x35, 0x2f, 0x85, 0xda, 0x8e, 0x75, 0xb2, 0xbb, 0xf0, 0x50, 0x8e, 0xe1, 0xc6,
0x43, 0x39, 0x86, 0x0f, 0x0f, 0xe5, 0x18, 0x1b, 0x1e, 0xc9, 0x31, 0xae, 0x78, 0x24, 0xc7, 0x78,
0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0xbe, 0x78, 0x24, 0xc7,
0xf0, 0xe1, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x51, 0x1c, 0x30, 0xb3, 0x92, 0xd8, 0xc0,
0xc1, 0x6f, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x72, 0x81, 0x1a, 0x91, 0x90, 0x01, 0x00, 0x00,
0xf0, 0xe1, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c,
0xc7, 0x10, 0xc5, 0x01, 0x33, 0x33, 0x89, 0x0d, 0x1c, 0x0d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff,
0xff, 0x5e, 0xce, 0x52, 0xb3, 0x98, 0x01, 0x00, 0x00,
}
+2
View File
@@ -162,7 +162,9 @@ func (sm *Manager) Get(ctx context.Context, id string) (Caller, error) {
go func() {
select {
case <-ctx.Done():
sm.mu.Lock()
sm.updateCondition.Broadcast()
sm.mu.Unlock()
}
}()
+2 -2
View File
@@ -24,7 +24,7 @@ const (
// Dialer returns a connection that can be used by the session
type Dialer func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error)
// Attachable defines a feature that can be expsed on a session
// Attachable defines a feature that can be exposed on a session
type Attachable interface {
Register(*grpc.Server)
}
@@ -66,7 +66,7 @@ func NewSession(ctx context.Context, name, sharedKey string) (*Session, error) {
return s, nil
}
// Allow enable a given service to be reachable through the grpc session
// Allow enables a given service to be reachable through the grpc session
func (s *Session) Allow(a Attachable) {
a.Register(s.grpcServer)
}