mirror of
https://github.com/GoogleContainerTools/kaniko
synced 2026-10-19 04:18:57 +02:00
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:
+66
@@ -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>
|
||||
+5
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
// +build !dfsecrets
|
||||
|
||||
package instructions
|
||||
|
||||
func isSecretMountsSupported() bool {
|
||||
return false
|
||||
}
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
// +build !dfssh
|
||||
|
||||
package instructions
|
||||
|
||||
func isSSHMountsSupported() bool {
|
||||
return false
|
||||
}
|
||||
Generated
Vendored
+87
-5
@@ -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
|
||||
}
|
||||
|
||||
Generated
Vendored
+63
@@ -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
|
||||
}
|
||||
Generated
Vendored
+61
@@ -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
|
||||
}
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
// +build dfsecrets
|
||||
|
||||
package instructions
|
||||
|
||||
func isSecretMountsSupported() bool {
|
||||
return true
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// +build dfssh
|
||||
|
||||
package instructions
|
||||
|
||||
func isSSHMountsSupported() bool {
|
||||
return true
|
||||
}
|
||||
+8
-3
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user