Signed-off-by: Tibor Vass <tibor@docker.com>
(cherry picked from commit a1cdd4bfcc515a862e18ac123836fcaa05d09b32)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -113,7 +113,9 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
|
| 113 | 113 |
return nil, err |
| 114 | 114 |
} |
| 115 | 115 |
|
| 116 |
- exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, opt.Rootless, opt.IdentityMapping) |
|
| 116 |
+ dns := getDNSConfig(opt.DNSConfig) |
|
| 117 |
+ |
|
| 118 |
+ exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, dns, opt.Rootless, opt.IdentityMapping) |
|
| 117 | 119 |
if err != nil {
|
| 118 | 120 |
return nil, err |
| 119 | 121 |
} |
| ... | ... |
@@ -8,9 +8,11 @@ import ( |
| 8 | 8 |
"strconv" |
| 9 | 9 |
"sync" |
| 10 | 10 |
|
| 11 |
+ "github.com/docker/docker/daemon/config" |
|
| 11 | 12 |
"github.com/docker/docker/pkg/idtools" |
| 12 | 13 |
"github.com/docker/libnetwork" |
| 13 | 14 |
"github.com/moby/buildkit/executor" |
| 15 |
+ "github.com/moby/buildkit/executor/oci" |
|
| 14 | 16 |
"github.com/moby/buildkit/executor/runcexecutor" |
| 15 | 17 |
"github.com/moby/buildkit/identity" |
| 16 | 18 |
"github.com/moby/buildkit/solver/pb" |
| ... | ... |
@@ -21,7 +23,7 @@ import ( |
| 21 | 21 |
|
| 22 | 22 |
const networkName = "bridge" |
| 23 | 23 |
|
| 24 |
-func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, rootless bool, idmap *idtools.IdentityMapping) (executor.Executor, error) {
|
|
| 24 |
+func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dnsConfig *oci.DNSConfig, rootless bool, idmap *idtools.IdentityMapping) (executor.Executor, error) {
|
|
| 25 | 25 |
networkProviders := map[pb.NetMode]network.Provider{
|
| 26 | 26 |
pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: filepath.Join(root, "net")},
|
| 27 | 27 |
pb.NetMode_HOST: network.NewHostProvider(), |
| ... | ... |
@@ -34,6 +36,7 @@ func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, ro |
| 34 | 34 |
Rootless: rootless, |
| 35 | 35 |
NoPivot: os.Getenv("DOCKER_RAMDISK") != "",
|
| 36 | 36 |
IdentityMapping: idmap, |
| 37 |
+ DNS: dnsConfig, |
|
| 37 | 38 |
}, networkProviders) |
| 38 | 39 |
} |
| 39 | 40 |
|
| ... | ... |
@@ -117,3 +120,14 @@ func (iface *lnInterface) Close() error {
|
| 117 | 117 |
} |
| 118 | 118 |
return iface.err |
| 119 | 119 |
} |
| 120 |
+ |
|
| 121 |
+func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig {
|
|
| 122 |
+ if cfg.DNS != nil || cfg.DNSSearch != nil || cfg.DNSOptions != nil {
|
|
| 123 |
+ return &oci.DNSConfig{
|
|
| 124 |
+ Nameservers: cfg.DNS, |
|
| 125 |
+ SearchDomains: cfg.DNSSearch, |
|
| 126 |
+ Options: cfg.DNSOptions, |
|
| 127 |
+ } |
|
| 128 |
+ } |
|
| 129 |
+ return nil |
|
| 130 |
+} |
| ... | ... |
@@ -5,13 +5,15 @@ import ( |
| 5 | 5 |
"errors" |
| 6 | 6 |
"io" |
| 7 | 7 |
|
| 8 |
+ "github.com/docker/docker/daemon/config" |
|
| 8 | 9 |
"github.com/docker/docker/pkg/idtools" |
| 9 | 10 |
"github.com/docker/libnetwork" |
| 10 | 11 |
"github.com/moby/buildkit/cache" |
| 11 | 12 |
"github.com/moby/buildkit/executor" |
| 13 |
+ "github.com/moby/buildkit/executor/oci" |
|
| 12 | 14 |
) |
| 13 | 15 |
|
| 14 |
-func newExecutor(_, _ string, _ libnetwork.NetworkController, _ bool, _ *idtools.IdentityMapping) (executor.Executor, error) {
|
|
| 16 |
+func newExecutor(_, _ string, _ libnetwork.NetworkController, _ *oci.DNSConfig, _ bool, _ *idtools.IdentityMapping) (executor.Executor, error) {
|
|
| 15 | 17 |
return &winExecutor{}, nil
|
| 16 | 18 |
} |
| 17 | 19 |
|
| ... | ... |
@@ -21,3 +23,7 @@ type winExecutor struct {
|
| 21 | 21 |
func (e *winExecutor) Exec(ctx context.Context, meta executor.Meta, rootfs cache.Mountable, mounts []executor.Mount, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error {
|
| 22 | 22 |
return errors.New("buildkit executor not implemented for windows")
|
| 23 | 23 |
} |
| 24 |
+ |
|
| 25 |
+func getDNSConfig(config.DNSConfig) *oci.DNSConfig {
|
|
| 26 |
+ return nil |
|
| 27 |
+} |
| ... | ... |
@@ -319,6 +319,7 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e |
| 319 | 319 |
BuilderConfig: config.Builder, |
| 320 | 320 |
Rootless: d.Rootless(), |
| 321 | 321 |
IdentityMapping: d.IdentityMapping(), |
| 322 |
+ DNSConfig: config.DNSConfig, |
|
| 322 | 323 |
}) |
| 323 | 324 |
if err != nil {
|
| 324 | 325 |
return opts, err |
| ... | ... |
@@ -109,6 +109,13 @@ type CommonTLSOptions struct {
|
| 109 | 109 |
KeyFile string `json:"tlskey,omitempty"` |
| 110 | 110 |
} |
| 111 | 111 |
|
| 112 |
+// DNSConfig defines the DNS configurations. |
|
| 113 |
+type DNSConfig struct {
|
|
| 114 |
+ DNS []string `json:"dns,omitempty"` |
|
| 115 |
+ DNSOptions []string `json:"dns-opts,omitempty"` |
|
| 116 |
+ DNSSearch []string `json:"dns-search,omitempty"` |
|
| 117 |
+} |
|
| 118 |
+ |
|
| 112 | 119 |
// CommonConfig defines the configuration of a docker daemon which is |
| 113 | 120 |
// common across platforms. |
| 114 | 121 |
// It includes json tags to deserialize configuration from a file |
| ... | ... |
@@ -119,9 +126,6 @@ type CommonConfig struct {
|
| 119 | 119 |
AutoRestart bool `json:"-"` |
| 120 | 120 |
Context map[string][]string `json:"-"` |
| 121 | 121 |
DisableBridge bool `json:"-"` |
| 122 |
- DNS []string `json:"dns,omitempty"` |
|
| 123 |
- DNSOptions []string `json:"dns-opts,omitempty"` |
|
| 124 |
- DNSSearch []string `json:"dns-search,omitempty"` |
|
| 125 | 122 |
ExecOptions []string `json:"exec-opts,omitempty"` |
| 126 | 123 |
GraphDriver string `json:"storage-driver,omitempty"` |
| 127 | 124 |
GraphOptions []string `json:"storage-opts,omitempty"` |
| ... | ... |
@@ -200,6 +204,7 @@ type CommonConfig struct {
|
| 200 | 200 |
|
| 201 | 201 |
MetricsAddress string `json:"metrics-addr"` |
| 202 | 202 |
|
| 203 |
+ DNSConfig |
|
| 203 | 204 |
LogConfig |
| 204 | 205 |
BridgeConfig // bridgeConfig holds bridge network specific configuration. |
| 205 | 206 |
NetworkConfig |
| ... | ... |
@@ -244,28 +244,36 @@ func TestValidateConfigurationErrors(t *testing.T) {
|
| 244 | 244 |
{
|
| 245 | 245 |
config: &Config{
|
| 246 | 246 |
CommonConfig: CommonConfig{
|
| 247 |
- DNS: []string{"1.1.1.1o"},
|
|
| 247 |
+ DNSConfig: DNSConfig{
|
|
| 248 |
+ DNS: []string{"1.1.1.1o"},
|
|
| 249 |
+ }, |
|
| 248 | 250 |
}, |
| 249 | 251 |
}, |
| 250 | 252 |
}, |
| 251 | 253 |
{
|
| 252 | 254 |
config: &Config{
|
| 253 | 255 |
CommonConfig: CommonConfig{
|
| 254 |
- DNS: []string{"2.2.2.2", "1.1.1.1o"},
|
|
| 256 |
+ DNSConfig: DNSConfig{
|
|
| 257 |
+ DNS: []string{"2.2.2.2", "1.1.1.1o"},
|
|
| 258 |
+ }, |
|
| 255 | 259 |
}, |
| 256 | 260 |
}, |
| 257 | 261 |
}, |
| 258 | 262 |
{
|
| 259 | 263 |
config: &Config{
|
| 260 | 264 |
CommonConfig: CommonConfig{
|
| 261 |
- DNSSearch: []string{"123456"},
|
|
| 265 |
+ DNSConfig: DNSConfig{
|
|
| 266 |
+ DNSSearch: []string{"123456"},
|
|
| 267 |
+ }, |
|
| 262 | 268 |
}, |
| 263 | 269 |
}, |
| 264 | 270 |
}, |
| 265 | 271 |
{
|
| 266 | 272 |
config: &Config{
|
| 267 | 273 |
CommonConfig: CommonConfig{
|
| 268 |
- DNSSearch: []string{"a.b.c", "123456"},
|
|
| 274 |
+ DNSConfig: DNSConfig{
|
|
| 275 |
+ DNSSearch: []string{"a.b.c", "123456"},
|
|
| 276 |
+ }, |
|
| 269 | 277 |
}, |
| 270 | 278 |
}, |
| 271 | 279 |
}, |
| ... | ... |
@@ -329,14 +337,18 @@ func TestValidateConfiguration(t *testing.T) {
|
| 329 | 329 |
{
|
| 330 | 330 |
config: &Config{
|
| 331 | 331 |
CommonConfig: CommonConfig{
|
| 332 |
- DNS: []string{"1.1.1.1"},
|
|
| 332 |
+ DNSConfig: DNSConfig{
|
|
| 333 |
+ DNS: []string{"1.1.1.1"},
|
|
| 334 |
+ }, |
|
| 333 | 335 |
}, |
| 334 | 336 |
}, |
| 335 | 337 |
}, |
| 336 | 338 |
{
|
| 337 | 339 |
config: &Config{
|
| 338 | 340 |
CommonConfig: CommonConfig{
|
| 339 |
- DNSSearch: []string{"a.b.c"},
|
|
| 341 |
+ DNSConfig: DNSConfig{
|
|
| 342 |
+ DNSSearch: []string{"a.b.c"},
|
|
| 343 |
+ }, |
|
| 340 | 344 |
}, |
| 341 | 345 |
}, |
| 342 | 346 |
}, |
| ... | ... |
@@ -27,7 +27,7 @@ github.com/imdario/mergo 7c29201646fa3de8506f70121347 |
| 27 | 27 |
golang.org/x/sync e225da77a7e68af35c70ccbf71af2b83e6acac3c |
| 28 | 28 |
|
| 29 | 29 |
# buildkit |
| 30 |
-github.com/moby/buildkit c24275065aca6605bd83c57c6735510f4ebeb6d9 |
|
| 30 |
+github.com/moby/buildkit a258bd18b2c55aac4e8a10a3074757d66d45cef6 |
|
| 31 | 31 |
github.com/tonistiigi/fsutil 3bbb99cdbd76619ab717299830c60f6f2a533a6b |
| 32 | 32 |
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 |
| 33 | 33 |
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 |
| ... | ... |
@@ -299,7 +299,7 @@ Run `make images` to build the images as `moby/buildkit:local` and `moby/buildki |
| 299 | 299 |
If you are running `moby/buildkit:master` or `moby/buildkit:master-rootless` as a Docker/Kubernetes container, you can use special `BUILDKIT_HOST` URL for connecting to the BuildKit daemon in the container: |
| 300 | 300 |
|
| 301 | 301 |
``` |
| 302 |
-export BUILDKIT_HOST=docker://<container> |
|
| 302 |
+export BUILDKIT_HOST=docker-container://<container> |
|
| 303 | 303 |
``` |
| 304 | 304 |
|
| 305 | 305 |
``` |
| ... | ... |
@@ -157,14 +157,14 @@ func (cm *cacheManager) get(ctx context.Context, id string, fromSnapshotter bool |
| 157 | 157 |
func (cm *cacheManager) getRecord(ctx context.Context, id string, fromSnapshotter bool, opts ...RefOption) (cr *cacheRecord, retErr error) {
|
| 158 | 158 |
if rec, ok := cm.records[id]; ok {
|
| 159 | 159 |
if rec.isDead() {
|
| 160 |
- return nil, errNotFound |
|
| 160 |
+ return nil, errors.Wrapf(errNotFound, "failed to get dead record %s", id) |
|
| 161 | 161 |
} |
| 162 | 162 |
return rec, nil |
| 163 | 163 |
} |
| 164 | 164 |
|
| 165 | 165 |
md, ok := cm.md.Get(id) |
| 166 | 166 |
if !ok && !fromSnapshotter {
|
| 167 |
- return nil, errNotFound |
|
| 167 |
+ return nil, errors.WithStack(errNotFound) |
|
| 168 | 168 |
} |
| 169 | 169 |
if mutableID := getEqualMutable(md); mutableID != "" {
|
| 170 | 170 |
mutable, err := cm.getRecord(ctx, mutableID, fromSnapshotter) |
| ... | ... |
@@ -222,7 +222,7 @@ func (cm *cacheManager) getRecord(ctx context.Context, id string, fromSnapshotte |
| 222 | 222 |
if err := rec.remove(ctx, true); err != nil {
|
| 223 | 223 |
return nil, err |
| 224 | 224 |
} |
| 225 |
- return nil, errNotFound |
|
| 225 |
+ return nil, errors.Wrapf(errNotFound, "failed to get deleted record %s", id) |
|
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 | 228 |
if err := initializeMetadata(rec, opts...); err != nil {
|
| ... | ... |
@@ -330,14 +330,14 @@ func (cm *cacheManager) Prune(ctx context.Context, ch chan client.UsageInfo, opt |
| 330 | 330 |
func (cm *cacheManager) pruneOnce(ctx context.Context, ch chan client.UsageInfo, opt client.PruneInfo) error {
|
| 331 | 331 |
filter, err := filters.ParseAll(opt.Filter...) |
| 332 | 332 |
if err != nil {
|
| 333 |
- return err |
|
| 333 |
+ return errors.Wrapf(err, "failed to parse prune filters %v", opt.Filter) |
|
| 334 | 334 |
} |
| 335 | 335 |
|
| 336 | 336 |
var check ExternalRefChecker |
| 337 | 337 |
if f := cm.PruneRefChecker; f != nil && (!opt.All || len(opt.Filter) > 0) {
|
| 338 | 338 |
c, err := f() |
| 339 | 339 |
if err != nil {
|
| 340 |
- return err |
|
| 340 |
+ return errors.WithStack(err) |
|
| 341 | 341 |
} |
| 342 | 342 |
check = c |
| 343 | 343 |
} |
| ... | ... |
@@ -549,7 +549,7 @@ func (cm *cacheManager) markShared(m map[string]*cacheUsageInfo) error {
|
| 549 | 549 |
} |
| 550 | 550 |
c, err := cm.PruneRefChecker() |
| 551 | 551 |
if err != nil {
|
| 552 |
- return err |
|
| 552 |
+ return errors.WithStack(err) |
|
| 553 | 553 |
} |
| 554 | 554 |
|
| 555 | 555 |
var markAllParentsShared func(string) |
| ... | ... |
@@ -590,7 +590,7 @@ type cacheUsageInfo struct {
|
| 590 | 590 |
func (cm *cacheManager) DiskUsage(ctx context.Context, opt client.DiskUsageInfo) ([]*client.UsageInfo, error) {
|
| 591 | 591 |
filter, err := filters.ParseAll(opt.Filter...) |
| 592 | 592 |
if err != nil {
|
| 593 |
- return nil, err |
|
| 593 |
+ return nil, errors.Wrapf(err, "failed to parse diskusage filters %v", opt.Filter) |
|
| 594 | 594 |
} |
| 595 | 595 |
|
| 596 | 596 |
cm.mu.Lock() |
| ... | ... |
@@ -55,7 +55,7 @@ func (s *Store) All() ([]*StorageItem, error) {
|
| 55 | 55 |
return nil |
| 56 | 56 |
}) |
| 57 | 57 |
}) |
| 58 |
- return out, err |
|
| 58 |
+ return out, errors.WithStack(err) |
|
| 59 | 59 |
} |
| 60 | 60 |
|
| 61 | 61 |
func (s *Store) Probe(index string) (bool, error) {
|
| ... | ... |
@@ -77,7 +77,7 @@ func (s *Store) Probe(index string) (bool, error) {
|
| 77 | 77 |
} |
| 78 | 78 |
return nil |
| 79 | 79 |
}) |
| 80 |
- return exists, err |
|
| 80 |
+ return exists, errors.WithStack(err) |
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
func (s *Store) Search(index string) ([]*StorageItem, error) {
|
| ... | ... |
@@ -114,7 +114,7 @@ func (s *Store) Search(index string) ([]*StorageItem, error) {
|
| 114 | 114 |
} |
| 115 | 115 |
return nil |
| 116 | 116 |
}) |
| 117 |
- return out, err |
|
| 117 |
+ return out, errors.WithStack(err) |
|
| 118 | 118 |
} |
| 119 | 119 |
|
| 120 | 120 |
func (s *Store) View(id string, fn func(b *bolt.Bucket) error) error {
|
| ... | ... |
@@ -132,7 +132,7 @@ func (s *Store) View(id string, fn func(b *bolt.Bucket) error) error {
|
| 132 | 132 |
} |
| 133 | 133 |
|
| 134 | 134 |
func (s *Store) Clear(id string) error {
|
| 135 |
- return s.db.Update(func(tx *bolt.Tx) error {
|
|
| 135 |
+ return errors.WithStack(s.db.Update(func(tx *bolt.Tx) error {
|
|
| 136 | 136 |
external := tx.Bucket([]byte(externalBucket)) |
| 137 | 137 |
if external != nil {
|
| 138 | 138 |
external.DeleteBucket([]byte(id)) |
| ... | ... |
@@ -160,21 +160,21 @@ func (s *Store) Clear(id string) error {
|
| 160 | 160 |
} |
| 161 | 161 |
} |
| 162 | 162 |
return main.DeleteBucket([]byte(id)) |
| 163 |
- }) |
|
| 163 |
+ })) |
|
| 164 | 164 |
} |
| 165 | 165 |
|
| 166 | 166 |
func (s *Store) Update(id string, fn func(b *bolt.Bucket) error) error {
|
| 167 |
- return s.db.Update(func(tx *bolt.Tx) error {
|
|
| 167 |
+ return errors.WithStack(s.db.Update(func(tx *bolt.Tx) error {
|
|
| 168 | 168 |
b, err := tx.CreateBucketIfNotExists([]byte(mainBucket)) |
| 169 | 169 |
if err != nil {
|
| 170 |
- return err |
|
| 170 |
+ return errors.WithStack(err) |
|
| 171 | 171 |
} |
| 172 | 172 |
b, err = b.CreateBucketIfNotExists([]byte(id)) |
| 173 | 173 |
if err != nil {
|
| 174 |
- return err |
|
| 174 |
+ return errors.WithStack(err) |
|
| 175 | 175 |
} |
| 176 | 176 |
return fn(b) |
| 177 |
- }) |
|
| 177 |
+ })) |
|
| 178 | 178 |
} |
| 179 | 179 |
|
| 180 | 180 |
func (s *Store) Get(id string) (*StorageItem, bool) {
|
| ... | ... |
@@ -200,7 +200,7 @@ func (s *Store) Get(id string) (*StorageItem, bool) {
|
| 200 | 200 |
} |
| 201 | 201 |
|
| 202 | 202 |
func (s *Store) Close() error {
|
| 203 |
- return s.db.Close() |
|
| 203 |
+ return errors.WithStack(s.db.Close()) |
|
| 204 | 204 |
} |
| 205 | 205 |
|
| 206 | 206 |
type StorageItem struct {
|
| ... | ... |
@@ -222,13 +222,13 @@ func newStorageItem(id string, b *bolt.Bucket, s *Store) (*StorageItem, error) {
|
| 222 | 222 |
var sv Value |
| 223 | 223 |
if len(v) > 0 {
|
| 224 | 224 |
if err := json.Unmarshal(v, &sv); err != nil {
|
| 225 |
- return err |
|
| 225 |
+ return errors.WithStack(err) |
|
| 226 | 226 |
} |
| 227 | 227 |
si.values[string(k)] = &sv |
| 228 | 228 |
} |
| 229 | 229 |
return nil |
| 230 | 230 |
}); err != nil {
|
| 231 |
- return si, err |
|
| 231 |
+ return si, errors.WithStack(err) |
|
| 232 | 232 |
} |
| 233 | 233 |
} |
| 234 | 234 |
return si, nil |
| ... | ... |
@@ -283,23 +283,23 @@ func (s *StorageItem) GetExternal(k string) ([]byte, error) {
|
| 283 | 283 |
return nil |
| 284 | 284 |
}) |
| 285 | 285 |
if err != nil {
|
| 286 |
- return nil, err |
|
| 286 |
+ return nil, errors.WithStack(err) |
|
| 287 | 287 |
} |
| 288 | 288 |
return dt, nil |
| 289 | 289 |
} |
| 290 | 290 |
|
| 291 | 291 |
func (s *StorageItem) SetExternal(k string, dt []byte) error {
|
| 292 |
- return s.storage.db.Update(func(tx *bolt.Tx) error {
|
|
| 292 |
+ return errors.WithStack(s.storage.db.Update(func(tx *bolt.Tx) error {
|
|
| 293 | 293 |
b, err := tx.CreateBucketIfNotExists([]byte(externalBucket)) |
| 294 | 294 |
if err != nil {
|
| 295 |
- return err |
|
| 295 |
+ return errors.WithStack(err) |
|
| 296 | 296 |
} |
| 297 | 297 |
b, err = b.CreateBucketIfNotExists([]byte(s.id)) |
| 298 | 298 |
if err != nil {
|
| 299 |
- return err |
|
| 299 |
+ return errors.WithStack(err) |
|
| 300 | 300 |
} |
| 301 | 301 |
return b.Put([]byte(k), dt) |
| 302 |
- }) |
|
| 302 |
+ })) |
|
| 303 | 303 |
} |
| 304 | 304 |
|
| 305 | 305 |
func (s *StorageItem) Queue(fn func(b *bolt.Bucket) error) {
|
| ... | ... |
@@ -311,15 +311,15 @@ func (s *StorageItem) Queue(fn func(b *bolt.Bucket) error) {
|
| 311 | 311 |
func (s *StorageItem) Commit() error {
|
| 312 | 312 |
s.mu.Lock() |
| 313 | 313 |
defer s.mu.Unlock() |
| 314 |
- return s.Update(func(b *bolt.Bucket) error {
|
|
| 314 |
+ return errors.WithStack(s.Update(func(b *bolt.Bucket) error {
|
|
| 315 | 315 |
for _, fn := range s.queue {
|
| 316 | 316 |
if err := fn(b); err != nil {
|
| 317 |
- return err |
|
| 317 |
+ return errors.WithStack(err) |
|
| 318 | 318 |
} |
| 319 | 319 |
} |
| 320 | 320 |
s.queue = s.queue[:0] |
| 321 | 321 |
return nil |
| 322 |
- }) |
|
| 322 |
+ })) |
|
| 323 | 323 |
} |
| 324 | 324 |
|
| 325 | 325 |
func (s *StorageItem) Indexes() (out []string) {
|
| ... | ... |
@@ -341,18 +341,18 @@ func (s *StorageItem) SetValue(b *bolt.Bucket, key string, v *Value) error {
|
| 341 | 341 |
} |
| 342 | 342 |
dt, err := json.Marshal(v) |
| 343 | 343 |
if err != nil {
|
| 344 |
- return err |
|
| 344 |
+ return errors.WithStack(err) |
|
| 345 | 345 |
} |
| 346 | 346 |
if err := b.Put([]byte(key), dt); err != nil {
|
| 347 |
- return err |
|
| 347 |
+ return errors.WithStack(err) |
|
| 348 | 348 |
} |
| 349 | 349 |
if v.Index != "" {
|
| 350 | 350 |
b, err := b.Tx().CreateBucketIfNotExists([]byte(indexBucket)) |
| 351 | 351 |
if err != nil {
|
| 352 |
- return err |
|
| 352 |
+ return errors.WithStack(err) |
|
| 353 | 353 |
} |
| 354 | 354 |
if err := b.Put([]byte(indexKey(v.Index, s.ID())), []byte{}); err != nil {
|
| 355 |
- return err |
|
| 355 |
+ return errors.WithStack(err) |
|
| 356 | 356 |
} |
| 357 | 357 |
} |
| 358 | 358 |
s.values[key] = v |
| ... | ... |
@@ -367,14 +367,13 @@ type Value struct {
|
| 367 | 367 |
func NewValue(v interface{}) (*Value, error) {
|
| 368 | 368 |
dt, err := json.Marshal(v) |
| 369 | 369 |
if err != nil {
|
| 370 |
- return nil, err |
|
| 370 |
+ return nil, errors.WithStack(err) |
|
| 371 | 371 |
} |
| 372 | 372 |
return &Value{Value: json.RawMessage(dt)}, nil
|
| 373 | 373 |
} |
| 374 | 374 |
|
| 375 | 375 |
func (v *Value) Unmarshal(target interface{}) error {
|
| 376 |
- err := json.Unmarshal(v.Value, target) |
|
| 377 |
- return err |
|
| 376 |
+ return errors.WithStack(json.Unmarshal(v.Value, target)) |
|
| 378 | 377 |
} |
| 379 | 378 |
|
| 380 | 379 |
func indexKey(index, target string) string {
|
| ... | ... |
@@ -190,7 +190,7 @@ func (cr *cacheRecord) remove(ctx context.Context, removeSnapshot bool) error {
|
| 190 | 190 |
} |
| 191 | 191 |
if removeSnapshot {
|
| 192 | 192 |
if err := cr.cm.Snapshotter.Remove(ctx, cr.ID()); err != nil {
|
| 193 |
- return err |
|
| 193 |
+ return errors.Wrapf(err, "failed to remove %s", cr.ID()) |
|
| 194 | 194 |
} |
| 195 | 195 |
} |
| 196 | 196 |
if err := cr.cm.md.Clear(cr.ID()); err != nil {
|
| ... | ... |
@@ -259,7 +259,7 @@ func (sr *immutableRef) release(ctx context.Context) error {
|
| 259 | 259 |
if len(sr.refs) == 0 {
|
| 260 | 260 |
if sr.viewMount != nil { // TODO: release viewMount earlier if possible
|
| 261 | 261 |
if err := sr.cm.Snapshotter.Remove(ctx, sr.view); err != nil {
|
| 262 |
- return err |
|
| 262 |
+ return errors.Wrapf(err, "failed to remove view %s", sr.view) |
|
| 263 | 263 |
} |
| 264 | 264 |
sr.view = "" |
| 265 | 265 |
sr.viewMount = nil |
| ... | ... |
@@ -100,7 +100,7 @@ func readBlob(ctx context.Context, provider content.Provider, desc ocispec.Descr |
| 100 | 100 |
} |
| 101 | 101 |
} |
| 102 | 102 |
} |
| 103 |
- return dt, err |
|
| 103 |
+ return dt, errors.WithStack(err) |
|
| 104 | 104 |
} |
| 105 | 105 |
|
| 106 | 106 |
func (ci *contentCacheImporter) importInlineCache(ctx context.Context, dt []byte, id string, w worker.Worker) (solver.CacheManager, error) {
|
| ... | ... |
@@ -120,7 +120,7 @@ func (ci *contentCacheImporter) importInlineCache(ctx context.Context, dt []byte |
| 120 | 120 |
var m ocispec.Manifest |
| 121 | 121 |
|
| 122 | 122 |
if err := json.Unmarshal(dt, &m); err != nil {
|
| 123 |
- return err |
|
| 123 |
+ return errors.WithStack(err) |
|
| 124 | 124 |
} |
| 125 | 125 |
|
| 126 | 126 |
if m.Config.Digest == "" || len(m.Layers) == 0 {
|
| ... | ... |
@@ -129,13 +129,13 @@ func (ci *contentCacheImporter) importInlineCache(ctx context.Context, dt []byte |
| 129 | 129 |
|
| 130 | 130 |
p, err := content.ReadBlob(ctx, ci.provider, m.Config) |
| 131 | 131 |
if err != nil {
|
| 132 |
- return err |
|
| 132 |
+ return errors.WithStack(err) |
|
| 133 | 133 |
} |
| 134 | 134 |
|
| 135 | 135 |
var img image |
| 136 | 136 |
|
| 137 | 137 |
if err := json.Unmarshal(p, &img); err != nil {
|
| 138 |
- return err |
|
| 138 |
+ return errors.WithStack(err) |
|
| 139 | 139 |
} |
| 140 | 140 |
|
| 141 | 141 |
if len(img.Rootfs.DiffIDs) != len(m.Layers) {
|
| ... | ... |
@@ -149,7 +149,7 @@ func (ci *contentCacheImporter) importInlineCache(ctx context.Context, dt []byte |
| 149 | 149 |
|
| 150 | 150 |
var config v1.CacheConfig |
| 151 | 151 |
if err := json.Unmarshal(img.Cache, &config.Records); err != nil {
|
| 152 |
- return err |
|
| 152 |
+ return errors.WithStack(err) |
|
| 153 | 153 |
} |
| 154 | 154 |
|
| 155 | 155 |
createdDates, createdMsg, err := parseCreatedLayerInfo(img) |
| ... | ... |
@@ -181,7 +181,7 @@ func (ci *contentCacheImporter) importInlineCache(ctx context.Context, dt []byte |
| 181 | 181 |
|
| 182 | 182 |
dt, err = json.Marshal(config) |
| 183 | 183 |
if err != nil {
|
| 184 |
- return err |
|
| 184 |
+ return errors.WithStack(err) |
|
| 185 | 185 |
} |
| 186 | 186 |
|
| 187 | 187 |
mu.Lock() |
| ... | ... |
@@ -217,7 +217,7 @@ func (ci *contentCacheImporter) allDistributionManifests(ctx context.Context, dt |
| 217 | 217 |
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: |
| 218 | 218 |
var index ocispec.Index |
| 219 | 219 |
if err := json.Unmarshal(dt, &index); err != nil {
|
| 220 |
- return err |
|
| 220 |
+ return errors.WithStack(err) |
|
| 221 | 221 |
} |
| 222 | 222 |
|
| 223 | 223 |
for _, d := range index.Manifests {
|
| ... | ... |
@@ -226,7 +226,7 @@ func (ci *contentCacheImporter) allDistributionManifests(ctx context.Context, dt |
| 226 | 226 |
} |
| 227 | 227 |
p, err := content.ReadBlob(ctx, ci.provider, d) |
| 228 | 228 |
if err != nil {
|
| 229 |
- return err |
|
| 229 |
+ return errors.WithStack(err) |
|
| 230 | 230 |
} |
| 231 | 231 |
if err := ci.allDistributionManifests(ctx, p, m); err != nil {
|
| 232 | 232 |
return err |
| ... | ... |
@@ -254,7 +254,7 @@ func (cs *cacheResultStorage) Load(ctx context.Context, res solver.CacheResult) |
| 254 | 254 |
|
| 255 | 255 |
ref, err := cs.w.FromRemote(ctx, item.result) |
| 256 | 256 |
if err != nil {
|
| 257 |
- return nil, err |
|
| 257 |
+ return nil, errors.Wrap(err, "failed to load result from remote") |
|
| 258 | 258 |
} |
| 259 | 259 |
return worker.NewWorkerRefResult(ref, cs.w), nil |
| 260 | 260 |
} |
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
func Parse(configJSON []byte, provider DescriptorProvider, t solver.CacheExporterTarget) error {
|
| 13 | 13 |
var config CacheConfig |
| 14 | 14 |
if err := json.Unmarshal(configJSON, &config); err != nil {
|
| 15 |
- return err |
|
| 15 |
+ return errors.WithStack(err) |
|
| 16 | 16 |
} |
| 17 | 17 |
|
| 18 | 18 |
return ParseConfig(config, provider, t) |
| ... | ... |
@@ -61,23 +61,23 @@ func ReadFile(ctx context.Context, ref cache.ImmutableRef, req ReadRequest) ([]b |
| 61 | 61 |
err := withMount(ctx, ref, func(root string) error {
|
| 62 | 62 |
fp, err := fs.RootPath(root, req.Filename) |
| 63 | 63 |
if err != nil {
|
| 64 |
- return err |
|
| 64 |
+ return errors.WithStack(err) |
|
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 | 67 |
if req.Range == nil {
|
| 68 | 68 |
dt, err = ioutil.ReadFile(fp) |
| 69 | 69 |
if err != nil {
|
| 70 |
- return err |
|
| 70 |
+ return errors.WithStack(err) |
|
| 71 | 71 |
} |
| 72 | 72 |
} else {
|
| 73 | 73 |
f, err := os.Open(fp) |
| 74 | 74 |
if err != nil {
|
| 75 |
- return err |
|
| 75 |
+ return errors.WithStack(err) |
|
| 76 | 76 |
} |
| 77 | 77 |
dt, err = ioutil.ReadAll(io.NewSectionReader(f, int64(req.Range.Offset), int64(req.Range.Length))) |
| 78 | 78 |
f.Close() |
| 79 | 79 |
if err != nil {
|
| 80 |
- return err |
|
| 80 |
+ return errors.WithStack(err) |
|
| 81 | 81 |
} |
| 82 | 82 |
} |
| 83 | 83 |
return nil |
| ... | ... |
@@ -101,7 +101,7 @@ func ReadDir(ctx context.Context, ref cache.ImmutableRef, req ReadDirRequest) ([ |
| 101 | 101 |
err := withMount(ctx, ref, func(root string) error {
|
| 102 | 102 |
fp, err := fs.RootPath(root, req.Path) |
| 103 | 103 |
if err != nil {
|
| 104 |
- return err |
|
| 104 |
+ return errors.WithStack(err) |
|
| 105 | 105 |
} |
| 106 | 106 |
return fsutil.Walk(ctx, fp, &wo, func(path string, info os.FileInfo, err error) error {
|
| 107 | 107 |
if err != nil {
|
| ... | ... |
@@ -128,10 +128,10 @@ func StatFile(ctx context.Context, ref cache.ImmutableRef, path string) (*fstype |
| 128 | 128 |
err := withMount(ctx, ref, func(root string) error {
|
| 129 | 129 |
fp, err := fs.RootPath(root, path) |
| 130 | 130 |
if err != nil {
|
| 131 |
- return err |
|
| 131 |
+ return errors.WithStack(err) |
|
| 132 | 132 |
} |
| 133 | 133 |
if st, err = fsutil.Stat(fp); err != nil {
|
| 134 |
- return err |
|
| 134 |
+ return errors.WithStack(err) |
|
| 135 | 135 |
} |
| 136 | 136 |
return nil |
| 137 | 137 |
}) |
| ... | ... |
@@ -427,11 +427,13 @@ func Security(s pb.SecurityMode) RunOption {
|
| 427 | 427 |
} |
| 428 | 428 |
|
| 429 | 429 |
func Shlex(str string) RunOption {
|
| 430 |
- return Shlexf(str) |
|
| 430 |
+ return runOptionFunc(func(ei *ExecInfo) {
|
|
| 431 |
+ ei.State = shlexf(str, false)(ei.State) |
|
| 432 |
+ }) |
|
| 431 | 433 |
} |
| 432 | 434 |
func Shlexf(str string, v ...interface{}) RunOption {
|
| 433 | 435 |
return runOptionFunc(func(ei *ExecInfo) {
|
| 434 |
- ei.State = shlexf(str, v...)(ei.State) |
|
| 436 |
+ ei.State = shlexf(str, true, v...)(ei.State) |
|
| 435 | 437 |
}) |
| 436 | 438 |
} |
| 437 | 439 |
|
| ... | ... |
@@ -442,7 +444,9 @@ func Args(a []string) RunOption {
|
| 442 | 442 |
} |
| 443 | 443 |
|
| 444 | 444 |
func AddEnv(key, value string) RunOption {
|
| 445 |
- return AddEnvf(key, value) |
|
| 445 |
+ return runOptionFunc(func(ei *ExecInfo) {
|
|
| 446 |
+ ei.State = ei.State.AddEnv(key, value) |
|
| 447 |
+ }) |
|
| 446 | 448 |
} |
| 447 | 449 |
|
| 448 | 450 |
func AddEnvf(key, value string, v ...interface{}) RunOption {
|
| ... | ... |
@@ -458,7 +462,9 @@ func User(str string) RunOption {
|
| 458 | 458 |
} |
| 459 | 459 |
|
| 460 | 460 |
func Dir(str string) RunOption {
|
| 461 |
- return Dirf(str) |
|
| 461 |
+ return runOptionFunc(func(ei *ExecInfo) {
|
|
| 462 |
+ ei.State = ei.State.Dir(str) |
|
| 463 |
+ }) |
|
| 462 | 464 |
} |
| 463 | 465 |
func Dirf(str string, v ...interface{}) RunOption {
|
| 464 | 466 |
return runOptionFunc(func(ei *ExecInfo) {
|
| ... | ... |
@@ -24,19 +24,24 @@ var ( |
| 24 | 24 |
keySecurity = contextKeyT("llb.security")
|
| 25 | 25 |
) |
| 26 | 26 |
|
| 27 |
-func addEnvf(key, value string, v ...interface{}) StateOption {
|
|
| 27 |
+func addEnvf(key, value string, replace bool, v ...interface{}) StateOption {
|
|
| 28 |
+ if replace {
|
|
| 29 |
+ value = fmt.Sprintf(value, v...) |
|
| 30 |
+ } |
|
| 28 | 31 |
return func(s State) State {
|
| 29 |
- return s.WithValue(keyEnv, getEnv(s).AddOrReplace(key, fmt.Sprintf(value, v...))) |
|
| 32 |
+ return s.WithValue(keyEnv, getEnv(s).AddOrReplace(key, value)) |
|
| 30 | 33 |
} |
| 31 | 34 |
} |
| 32 | 35 |
|
| 33 | 36 |
func dir(str string) StateOption {
|
| 34 |
- return dirf(str) |
|
| 37 |
+ return dirf(str, false) |
|
| 35 | 38 |
} |
| 36 | 39 |
|
| 37 |
-func dirf(str string, v ...interface{}) StateOption {
|
|
| 40 |
+func dirf(value string, replace bool, v ...interface{}) StateOption {
|
|
| 41 |
+ if replace {
|
|
| 42 |
+ value = fmt.Sprintf(value, v...) |
|
| 43 |
+ } |
|
| 38 | 44 |
return func(s State) State {
|
| 39 |
- value := fmt.Sprintf(str, v...) |
|
| 40 | 45 |
if !path.IsAbs(value) {
|
| 41 | 46 |
prev := getDir(s) |
| 42 | 47 |
if prev == "" {
|
| ... | ... |
@@ -100,9 +105,12 @@ func args(args ...string) StateOption {
|
| 100 | 100 |
} |
| 101 | 101 |
} |
| 102 | 102 |
|
| 103 |
-func shlexf(str string, v ...interface{}) StateOption {
|
|
| 103 |
+func shlexf(str string, replace bool, v ...interface{}) StateOption {
|
|
| 104 |
+ if replace {
|
|
| 105 |
+ str = fmt.Sprintf(str, v...) |
|
| 106 |
+ } |
|
| 104 | 107 |
return func(s State) State {
|
| 105 |
- arg, err := shlex.Split(fmt.Sprintf(str, v...)) |
|
| 108 |
+ arg, err := shlex.Split(str) |
|
| 106 | 109 |
if err != nil {
|
| 107 | 110 |
// TODO: handle error |
| 108 | 111 |
} |
| ... | ... |
@@ -240,18 +240,18 @@ func (s State) File(a *FileAction, opts ...ConstraintsOpt) State {
|
| 240 | 240 |
} |
| 241 | 241 |
|
| 242 | 242 |
func (s State) AddEnv(key, value string) State {
|
| 243 |
- return s.AddEnvf(key, value) |
|
| 243 |
+ return addEnvf(key, value, false)(s) |
|
| 244 | 244 |
} |
| 245 | 245 |
|
| 246 | 246 |
func (s State) AddEnvf(key, value string, v ...interface{}) State {
|
| 247 |
- return addEnvf(key, value, v...)(s) |
|
| 247 |
+ return addEnvf(key, value, true, v...)(s) |
|
| 248 | 248 |
} |
| 249 | 249 |
|
| 250 | 250 |
func (s State) Dir(str string) State {
|
| 251 |
- return s.Dirf(str) |
|
| 251 |
+ return dirf(str, false)(s) |
|
| 252 | 252 |
} |
| 253 | 253 |
func (s State) Dirf(str string, v ...interface{}) State {
|
| 254 |
- return dirf(str, v...)(s) |
|
| 254 |
+ return dirf(str, true, v...)(s) |
|
| 255 | 255 |
} |
| 256 | 256 |
|
| 257 | 257 |
func (s State) GetEnv(key string) (string, bool) {
|
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
|
| 9 | 9 |
"github.com/docker/docker/pkg/idtools" |
| 10 | 10 |
"github.com/docker/libnetwork/resolvconf" |
| 11 |
+ "github.com/docker/libnetwork/types" |
|
| 11 | 12 |
"github.com/moby/buildkit/util/flightcontrol" |
| 12 | 13 |
) |
| 13 | 14 |
|
| ... | ... |
@@ -15,7 +16,13 @@ var g flightcontrol.Group |
| 15 | 15 |
var notFirstRun bool |
| 16 | 16 |
var lastNotEmpty bool |
| 17 | 17 |
|
| 18 |
-func GetResolvConf(ctx context.Context, stateDir string, idmap *idtools.IdentityMapping) (string, error) {
|
|
| 18 |
+type DNSConfig struct {
|
|
| 19 |
+ Nameservers []string |
|
| 20 |
+ Options []string |
|
| 21 |
+ SearchDomains []string |
|
| 22 |
+} |
|
| 23 |
+ |
|
| 24 |
+func GetResolvConf(ctx context.Context, stateDir string, idmap *idtools.IdentityMapping, dns *DNSConfig) (string, error) {
|
|
| 19 | 25 |
p := filepath.Join(stateDir, "resolv.conf") |
| 20 | 26 |
_, err := g.Do(ctx, stateDir, func(ctx context.Context) (interface{}, error) {
|
| 21 | 27 |
generate := !notFirstRun |
| ... | ... |
@@ -61,9 +68,34 @@ func GetResolvConf(ctx context.Context, stateDir string, idmap *idtools.Identity |
| 61 | 61 |
dt = f.Content |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
- f, err = resolvconf.FilterResolvDNS(dt, true) |
|
| 65 |
- if err != nil {
|
|
| 66 |
- return "", err |
|
| 64 |
+ if dns != nil {
|
|
| 65 |
+ var ( |
|
| 66 |
+ dnsNameservers = resolvconf.GetNameservers(dt, types.IP) |
|
| 67 |
+ dnsSearchDomains = resolvconf.GetSearchDomains(dt) |
|
| 68 |
+ dnsOptions = resolvconf.GetOptions(dt) |
|
| 69 |
+ ) |
|
| 70 |
+ if len(dns.Nameservers) > 0 {
|
|
| 71 |
+ dnsNameservers = dns.Nameservers |
|
| 72 |
+ } |
|
| 73 |
+ if len(dns.SearchDomains) > 0 {
|
|
| 74 |
+ dnsSearchDomains = dns.SearchDomains |
|
| 75 |
+ } |
|
| 76 |
+ if len(dns.Options) > 0 {
|
|
| 77 |
+ dnsOptions = dns.Options |
|
| 78 |
+ } |
|
| 79 |
+ |
|
| 80 |
+ f, err = resolvconf.Build(p+".tmp", dnsNameservers, dnsSearchDomains, dnsOptions) |
|
| 81 |
+ if err != nil {
|
|
| 82 |
+ return "", err |
|
| 83 |
+ } |
|
| 84 |
+ } else {
|
|
| 85 |
+ // Logic seems odd here: why are we filtering localhost IPs |
|
| 86 |
+ // only if neither of the DNS configs were specified? |
|
| 87 |
+ // Logic comes from https://github.com/docker/libnetwork/blob/164a77ee6d24fb2b1d61f8ad3403a51d8453899e/sandbox_dns_unix.go#L230-L269 |
|
| 88 |
+ f, err = resolvconf.FilterResolvDNS(f.Content, true) |
|
| 89 |
+ if err != nil {
|
|
| 90 |
+ return "", err |
|
| 91 |
+ } |
|
| 67 | 92 |
} |
| 68 | 93 |
|
| 69 | 94 |
tmpPath := p + ".tmp" |
| 70 | 95 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,13 @@ |
| 0 |
+package oci |
|
| 1 |
+ |
|
| 2 |
+// ProcMode configures PID namespaces |
|
| 3 |
+type ProcessMode int |
|
| 4 |
+ |
|
| 5 |
+const ( |
|
| 6 |
+ // ProcessSandbox unshares pidns and mount procfs. |
|
| 7 |
+ ProcessSandbox ProcessMode = iota |
|
| 8 |
+ // NoProcessSandbox uses host pidns and bind-mount procfs. |
|
| 9 |
+ // Note that NoProcessSandbox allows build containers to kill (and potentially ptrace) an arbitrary process in the BuildKit host namespace. |
|
| 10 |
+ // NoProcessSandbox should be enabled only when the BuildKit is running in a container as an unprivileged user. |
|
| 11 |
+ NoProcessSandbox |
|
| 12 |
+) |
| ... | ... |
@@ -27,18 +27,6 @@ import ( |
| 27 | 27 |
|
| 28 | 28 |
// Ideally we don't have to import whole containerd just for the default spec |
| 29 | 29 |
|
| 30 |
-// ProcMode configures PID namespaces |
|
| 31 |
-type ProcessMode int |
|
| 32 |
- |
|
| 33 |
-const ( |
|
| 34 |
- // ProcessSandbox unshares pidns and mount procfs. |
|
| 35 |
- ProcessSandbox ProcessMode = iota |
|
| 36 |
- // NoProcessSandbox uses host pidns and bind-mount procfs. |
|
| 37 |
- // Note that NoProcessSandbox allows build containers to kill (and potentially ptrace) an arbitrary process in the BuildKit host namespace. |
|
| 38 |
- // NoProcessSandbox should be enabled only when the BuildKit is running in a container as an unprivileged user. |
|
| 39 |
- NoProcessSandbox |
|
| 40 |
-) |
|
| 41 |
- |
|
| 42 | 30 |
// GenerateSpec generates spec using containerd functionality. |
| 43 | 31 |
// opts are ignored for s.Process, s.Hostname, and s.Mounts . |
| 44 | 32 |
func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mount, id, resolvConf, hostsFile string, namespace network.Namespace, processMode ProcessMode, idmap *idtools.IdentityMapping, opts ...oci.SpecOpts) (*specs.Spec, func(), error) {
|
| ... | ... |
@@ -20,19 +20,11 @@ func GetUser(ctx context.Context, root, username string) (uint32, uint32, []uint |
| 20 | 20 |
return uid, gid, nil, nil |
| 21 | 21 |
} |
| 22 | 22 |
|
| 23 |
- passwdPath, err := user.GetPasswdPath() |
|
| 24 |
- if err != nil {
|
|
| 25 |
- return 0, 0, nil, err |
|
| 26 |
- } |
|
| 27 |
- groupPath, err := user.GetGroupPath() |
|
| 28 |
- if err != nil {
|
|
| 29 |
- return 0, 0, nil, err |
|
| 30 |
- } |
|
| 31 |
- passwdFile, err := openUserFile(root, passwdPath) |
|
| 23 |
+ passwdFile, err := openUserFile(root, "/etc/passwd") |
|
| 32 | 24 |
if err == nil {
|
| 33 | 25 |
defer passwdFile.Close() |
| 34 | 26 |
} |
| 35 |
- groupFile, err := openUserFile(root, groupPath) |
|
| 27 |
+ groupFile, err := openUserFile(root, "/etc/group") |
|
| 36 | 28 |
if err == nil {
|
| 37 | 29 |
defer groupFile.Close() |
| 38 | 30 |
} |
| ... | ... |
@@ -43,6 +43,7 @@ type Opt struct {
|
| 43 | 43 |
IdentityMapping *idtools.IdentityMapping |
| 44 | 44 |
// runc run --no-pivot (unrecommended) |
| 45 | 45 |
NoPivot bool |
| 46 |
+ DNS *oci.DNSConfig |
|
| 46 | 47 |
} |
| 47 | 48 |
|
| 48 | 49 |
var defaultCommandCandidates = []string{"buildkit-runc", "runc"}
|
| ... | ... |
@@ -57,6 +58,7 @@ type runcExecutor struct {
|
| 57 | 57 |
processMode oci.ProcessMode |
| 58 | 58 |
idmap *idtools.IdentityMapping |
| 59 | 59 |
noPivot bool |
| 60 |
+ dns *oci.DNSConfig |
|
| 60 | 61 |
} |
| 61 | 62 |
|
| 62 | 63 |
func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Executor, error) {
|
| ... | ... |
@@ -115,6 +117,7 @@ func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Ex |
| 115 | 115 |
processMode: opt.ProcessMode, |
| 116 | 116 |
idmap: opt.IdentityMapping, |
| 117 | 117 |
noPivot: opt.NoPivot, |
| 118 |
+ dns: opt.DNS, |
|
| 118 | 119 |
} |
| 119 | 120 |
return w, nil |
| 120 | 121 |
} |
| ... | ... |
@@ -134,7 +137,7 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache. |
| 134 | 134 |
logrus.Info("enabling HostNetworking")
|
| 135 | 135 |
} |
| 136 | 136 |
|
| 137 |
- resolvConf, err := oci.GetResolvConf(ctx, w.root, w.idmap) |
|
| 137 |
+ resolvConf, err := oci.GetResolvConf(ctx, w.root, w.idmap, w.dns) |
|
| 138 | 138 |
if err != nil {
|
| 139 | 139 |
return err |
| 140 | 140 |
} |
| ... | ... |
@@ -50,8 +50,8 @@ const ( |
| 50 | 50 |
keyContextSubDir = "contextsubdir" |
| 51 | 51 |
) |
| 52 | 52 |
|
| 53 |
-var httpPrefix = regexp.MustCompile("^https?://")
|
|
| 54 |
-var gitUrlPathWithFragmentSuffix = regexp.MustCompile("\\.git(?:#.+)?$")
|
|
| 53 |
+var httpPrefix = regexp.MustCompile(`^https?://`) |
|
| 54 |
+var gitUrlPathWithFragmentSuffix = regexp.MustCompile(`\.git(?:#.+)?$`) |
|
| 55 | 55 |
|
| 56 | 56 |
func Build(ctx context.Context, c client.Client) (*client.Result, error) {
|
| 57 | 57 |
opts := c.BuildOpts().Opts |
| ... | ... |
@@ -128,7 +128,7 @@ func (c *grpcClient) Run(ctx context.Context, f client.BuildFunc) (retError erro |
| 128 | 128 |
} |
| 129 | 129 |
} |
| 130 | 130 |
if retError != nil {
|
| 131 |
- st, _ := status.FromError(retError) |
|
| 131 |
+ st, _ := status.FromError(errors.Cause(retError)) |
|
| 132 | 132 |
stp := st.Proto() |
| 133 | 133 |
req.Error = &rpc.Status{
|
| 134 | 134 |
Code: stp.Code, |
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
|
| 6 | 6 |
"github.com/moby/buildkit/session" |
| 7 |
+ "github.com/pkg/errors" |
|
| 7 | 8 |
"google.golang.org/grpc/codes" |
| 8 | 9 |
"google.golang.org/grpc/status" |
| 9 | 10 |
) |
| ... | ... |
@@ -16,10 +17,10 @@ func CredentialsFunc(ctx context.Context, c session.Caller) func(string) (string |
| 16 | 16 |
Host: host, |
| 17 | 17 |
}) |
| 18 | 18 |
if err != nil {
|
| 19 |
- if st, ok := status.FromError(err); ok && st.Code() == codes.Unimplemented {
|
|
| 19 |
+ if st, ok := status.FromError(errors.Cause(err)); ok && st.Code() == codes.Unimplemented {
|
|
| 20 | 20 |
return "", "", nil |
| 21 | 21 |
} |
| 22 |
- return "", "", err |
|
| 22 |
+ return "", "", errors.WithStack(err) |
|
| 23 | 23 |
} |
| 24 | 24 |
return resp.Username, resp.Secret, nil |
| 25 | 25 |
} |
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"github.com/moby/buildkit/session" |
| 10 | 10 |
digest "github.com/opencontainers/go-digest" |
| 11 | 11 |
ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
| 12 |
+ "github.com/pkg/errors" |
|
| 12 | 13 |
"google.golang.org/grpc/metadata" |
| 13 | 14 |
) |
| 14 | 15 |
|
| ... | ... |
@@ -31,47 +32,53 @@ func (cs *callerContentStore) choose(ctx context.Context) context.Context {
|
| 31 | 31 |
|
| 32 | 32 |
func (cs *callerContentStore) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
|
| 33 | 33 |
ctx = cs.choose(ctx) |
| 34 |
- return cs.store.Info(ctx, dgst) |
|
| 34 |
+ info, err := cs.store.Info(ctx, dgst) |
|
| 35 |
+ return info, errors.WithStack(err) |
|
| 35 | 36 |
} |
| 36 | 37 |
|
| 37 | 38 |
func (cs *callerContentStore) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) {
|
| 38 | 39 |
ctx = cs.choose(ctx) |
| 39 |
- return cs.store.Update(ctx, info, fieldpaths...) |
|
| 40 |
+ info, err := cs.store.Update(ctx, info, fieldpaths...) |
|
| 41 |
+ return info, errors.WithStack(err) |
|
| 40 | 42 |
} |
| 41 | 43 |
|
| 42 | 44 |
func (cs *callerContentStore) Walk(ctx context.Context, fn content.WalkFunc, fs ...string) error {
|
| 43 | 45 |
ctx = cs.choose(ctx) |
| 44 |
- return cs.store.Walk(ctx, fn, fs...) |
|
| 46 |
+ return errors.WithStack(cs.store.Walk(ctx, fn, fs...)) |
|
| 45 | 47 |
} |
| 46 | 48 |
|
| 47 | 49 |
func (cs *callerContentStore) Delete(ctx context.Context, dgst digest.Digest) error {
|
| 48 | 50 |
ctx = cs.choose(ctx) |
| 49 |
- return cs.store.Delete(ctx, dgst) |
|
| 51 |
+ return errors.WithStack(cs.store.Delete(ctx, dgst)) |
|
| 50 | 52 |
} |
| 51 | 53 |
|
| 52 | 54 |
func (cs *callerContentStore) ListStatuses(ctx context.Context, fs ...string) ([]content.Status, error) {
|
| 53 | 55 |
ctx = cs.choose(ctx) |
| 54 |
- return cs.store.ListStatuses(ctx, fs...) |
|
| 56 |
+ resp, err := cs.store.ListStatuses(ctx, fs...) |
|
| 57 |
+ return resp, errors.WithStack(err) |
|
| 55 | 58 |
} |
| 56 | 59 |
|
| 57 | 60 |
func (cs *callerContentStore) Status(ctx context.Context, ref string) (content.Status, error) {
|
| 58 | 61 |
ctx = cs.choose(ctx) |
| 59 |
- return cs.store.Status(ctx, ref) |
|
| 62 |
+ st, err := cs.store.Status(ctx, ref) |
|
| 63 |
+ return st, errors.WithStack(err) |
|
| 60 | 64 |
} |
| 61 | 65 |
|
| 62 | 66 |
func (cs *callerContentStore) Abort(ctx context.Context, ref string) error {
|
| 63 | 67 |
ctx = cs.choose(ctx) |
| 64 |
- return cs.store.Abort(ctx, ref) |
|
| 68 |
+ return errors.WithStack(cs.store.Abort(ctx, ref)) |
|
| 65 | 69 |
} |
| 66 | 70 |
|
| 67 | 71 |
func (cs *callerContentStore) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
|
| 68 | 72 |
ctx = cs.choose(ctx) |
| 69 |
- return cs.store.Writer(ctx, opts...) |
|
| 73 |
+ w, err := cs.store.Writer(ctx, opts...) |
|
| 74 |
+ return w, errors.WithStack(err) |
|
| 70 | 75 |
} |
| 71 | 76 |
|
| 72 | 77 |
func (cs *callerContentStore) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
|
| 73 | 78 |
ctx = cs.choose(ctx) |
| 74 |
- return cs.store.ReaderAt(ctx, desc) |
|
| 79 |
+ ra, err := cs.store.ReaderAt(ctx, desc) |
|
| 80 |
+ return ra, errors.WithStack(err) |
|
| 75 | 81 |
} |
| 76 | 82 |
|
| 77 | 83 |
// NewCallerStore creates content.Store from session.Caller with specified storeID |
| ... | ... |
@@ -14,7 +14,7 @@ import ( |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 | 16 |
func sendDiffCopy(stream grpc.Stream, fs fsutil.FS, progress progressCb) error {
|
| 17 |
- return fsutil.Send(stream.Context(), stream, fs, progress) |
|
| 17 |
+ return errors.WithStack(fsutil.Send(stream.Context(), stream, fs, progress)) |
|
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 | 20 |
func newStreamWriter(stream grpc.ClientStream) io.WriteCloser {
|
| ... | ... |
@@ -29,7 +29,7 @@ type bufferedWriteCloser struct {
|
| 29 | 29 |
|
| 30 | 30 |
func (bwc *bufferedWriteCloser) Close() error {
|
| 31 | 31 |
if err := bwc.Writer.Flush(); err != nil {
|
| 32 |
- return err |
|
| 32 |
+ return errors.WithStack(err) |
|
| 33 | 33 |
} |
| 34 | 34 |
return bwc.Closer.Close() |
| 35 | 35 |
} |
| ... | ... |
@@ -40,19 +40,19 @@ type streamWriterCloser struct {
|
| 40 | 40 |
|
| 41 | 41 |
func (wc *streamWriterCloser) Write(dt []byte) (int, error) {
|
| 42 | 42 |
if err := wc.ClientStream.SendMsg(&BytesMessage{Data: dt}); err != nil {
|
| 43 |
- return 0, err |
|
| 43 |
+ return 0, errors.WithStack(err) |
|
| 44 | 44 |
} |
| 45 | 45 |
return len(dt), nil |
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 | 48 |
func (wc *streamWriterCloser) Close() error {
|
| 49 | 49 |
if err := wc.ClientStream.CloseSend(); err != nil {
|
| 50 |
- return err |
|
| 50 |
+ return errors.WithStack(err) |
|
| 51 | 51 |
} |
| 52 | 52 |
// block until receiver is done |
| 53 | 53 |
var bm BytesMessage |
| 54 | 54 |
if err := wc.ClientStream.RecvMsg(&bm); err != io.EOF {
|
| 55 |
- return err |
|
| 55 |
+ return errors.WithStack(err) |
|
| 56 | 56 |
} |
| 57 | 57 |
return nil |
| 58 | 58 |
} |
| ... | ... |
@@ -69,19 +69,19 @@ func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progres |
| 69 | 69 |
cf = cu.HandleChange |
| 70 | 70 |
ch = cu.ContentHasher() |
| 71 | 71 |
} |
| 72 |
- return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
|
|
| 72 |
+ return errors.WithStack(fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
|
|
| 73 | 73 |
NotifyHashed: cf, |
| 74 | 74 |
ContentHasher: ch, |
| 75 | 75 |
ProgressCb: progress, |
| 76 | 76 |
Filter: fsutil.FilterFunc(filter), |
| 77 |
- }) |
|
| 77 |
+ })) |
|
| 78 | 78 |
} |
| 79 | 79 |
|
| 80 | 80 |
func syncTargetDiffCopy(ds grpc.Stream, dest string) error {
|
| 81 | 81 |
if err := os.MkdirAll(dest, 0700); err != nil {
|
| 82 |
- return err |
|
| 82 |
+ return errors.Wrapf(err, "failed to create synctarget dest dir %s", dest) |
|
| 83 | 83 |
} |
| 84 |
- return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
|
|
| 84 |
+ return errors.WithStack(fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
|
|
| 85 | 85 |
Merge: true, |
| 86 | 86 |
Filter: func() func(string, *fstypes.Stat) bool {
|
| 87 | 87 |
uid := os.Getuid() |
| ... | ... |
@@ -92,7 +92,7 @@ func syncTargetDiffCopy(ds grpc.Stream, dest string) error {
|
| 92 | 92 |
return true |
| 93 | 93 |
} |
| 94 | 94 |
}(), |
| 95 |
- }) |
|
| 95 |
+ })) |
|
| 96 | 96 |
} |
| 97 | 97 |
|
| 98 | 98 |
func writeTargetFile(ds grpc.Stream, wc io.WriteCloser) error {
|
| ... | ... |
@@ -102,10 +102,10 @@ func writeTargetFile(ds grpc.Stream, wc io.WriteCloser) error {
|
| 102 | 102 |
if errors.Cause(err) == io.EOF {
|
| 103 | 103 |
return nil |
| 104 | 104 |
} |
| 105 |
- return err |
|
| 105 |
+ return errors.WithStack(err) |
|
| 106 | 106 |
} |
| 107 | 107 |
if _, err := wc.Write(bm.Data); err != nil {
|
| 108 |
- return err |
|
| 108 |
+ return errors.WithStack(err) |
|
| 109 | 109 |
} |
| 110 | 110 |
} |
| 111 | 111 |
} |
| ... | ... |
@@ -275,7 +275,7 @@ func CopyToCaller(ctx context.Context, fs fsutil.FS, c session.Caller, progress |
| 275 | 275 |
|
| 276 | 276 |
cc, err := client.DiffCopy(ctx) |
| 277 | 277 |
if err != nil {
|
| 278 |
- return err |
|
| 278 |
+ return errors.WithStack(err) |
|
| 279 | 279 |
} |
| 280 | 280 |
|
| 281 | 281 |
return sendDiffCopy(cc, fs, progress) |
| ... | ... |
@@ -291,7 +291,7 @@ func CopyFileWriter(ctx context.Context, c session.Caller) (io.WriteCloser, erro |
| 291 | 291 |
|
| 292 | 292 |
cc, err := client.DiffCopy(ctx) |
| 293 | 293 |
if err != nil {
|
| 294 |
- return nil, err |
|
| 294 |
+ return nil, errors.WithStack(err) |
|
| 295 | 295 |
} |
| 296 | 296 |
|
| 297 | 297 |
return newStreamWriter(cc), nil |
| ... | ... |
@@ -21,10 +21,10 @@ func GetSecret(ctx context.Context, c session.Caller, id string) ([]byte, error) |
| 21 | 21 |
ID: id, |
| 22 | 22 |
}) |
| 23 | 23 |
if err != nil {
|
| 24 |
- if st, ok := status.FromError(err); ok && (st.Code() == codes.Unimplemented || st.Code() == codes.NotFound) {
|
|
| 24 |
+ if st, ok := status.FromError(errors.Cause(err)); ok && (st.Code() == codes.Unimplemented || st.Code() == codes.NotFound) {
|
|
| 25 | 25 |
return nil, errors.Wrapf(ErrNotFound, "secret %s not found", id) |
| 26 | 26 |
} |
| 27 |
- return nil, err |
|
| 27 |
+ return nil, errors.WithStack(err) |
|
| 28 | 28 |
} |
| 29 | 29 |
return resp.Data, nil |
| 30 | 30 |
} |
| ... | ... |
@@ -3,6 +3,7 @@ package sshforward |
| 3 | 3 |
import ( |
| 4 | 4 |
io "io" |
| 5 | 5 |
|
| 6 |
+ "github.com/pkg/errors" |
|
| 6 | 7 |
context "golang.org/x/net/context" |
| 7 | 8 |
"golang.org/x/sync/errgroup" |
| 8 | 9 |
"google.golang.org/grpc" |
| ... | ... |
@@ -19,7 +20,7 @@ func Copy(ctx context.Context, conn io.ReadWriteCloser, stream grpc.Stream) erro |
| 19 | 19 |
return nil |
| 20 | 20 |
} |
| 21 | 21 |
conn.Close() |
| 22 |
- return err |
|
| 22 |
+ return errors.WithStack(err) |
|
| 23 | 23 |
} |
| 24 | 24 |
select {
|
| 25 | 25 |
case <-ctx.Done(): |
| ... | ... |
@@ -29,7 +30,7 @@ func Copy(ctx context.Context, conn io.ReadWriteCloser, stream grpc.Stream) erro |
| 29 | 29 |
} |
| 30 | 30 |
if _, err := conn.Write(p.Data); err != nil {
|
| 31 | 31 |
conn.Close() |
| 32 |
- return err |
|
| 32 |
+ return errors.WithStack(err) |
|
| 33 | 33 |
} |
| 34 | 34 |
p.Data = p.Data[:0] |
| 35 | 35 |
} |
| ... | ... |
@@ -43,7 +44,7 @@ func Copy(ctx context.Context, conn io.ReadWriteCloser, stream grpc.Stream) erro |
| 43 | 43 |
case err == io.EOF: |
| 44 | 44 |
return nil |
| 45 | 45 |
case err != nil: |
| 46 |
- return err |
|
| 46 |
+ return errors.WithStack(err) |
|
| 47 | 47 |
} |
| 48 | 48 |
select {
|
| 49 | 49 |
case <-ctx.Done(): |
| ... | ... |
@@ -52,7 +53,7 @@ func Copy(ctx context.Context, conn io.ReadWriteCloser, stream grpc.Stream) erro |
| 52 | 52 |
} |
| 53 | 53 |
p := &BytesMessage{Data: buf[:n]}
|
| 54 | 54 |
if err := stream.SendMsg(p); err != nil {
|
| 55 |
- return err |
|
| 55 |
+ return errors.WithStack(err) |
|
| 56 | 56 |
} |
| 57 | 57 |
} |
| 58 | 58 |
}) |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"path/filepath" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/moby/buildkit/session" |
| 10 |
+ "github.com/pkg/errors" |
|
| 10 | 11 |
context "golang.org/x/net/context" |
| 11 | 12 |
"golang.org/x/sync/errgroup" |
| 12 | 13 |
"google.golang.org/grpc/metadata" |
| ... | ... |
@@ -65,7 +66,7 @@ type SocketOpt struct {
|
| 65 | 65 |
func MountSSHSocket(ctx context.Context, c session.Caller, opt SocketOpt) (sockPath string, closer func() error, err error) {
|
| 66 | 66 |
dir, err := ioutil.TempDir("", ".buildkit-ssh-sock")
|
| 67 | 67 |
if err != nil {
|
| 68 |
- return "", nil, err |
|
| 68 |
+ return "", nil, errors.WithStack(err) |
|
| 69 | 69 |
} |
| 70 | 70 |
|
| 71 | 71 |
defer func() {
|
| ... | ... |
@@ -78,16 +79,16 @@ func MountSSHSocket(ctx context.Context, c session.Caller, opt SocketOpt) (sockP |
| 78 | 78 |
|
| 79 | 79 |
l, err := net.Listen("unix", sockPath)
|
| 80 | 80 |
if err != nil {
|
| 81 |
- return "", nil, err |
|
| 81 |
+ return "", nil, errors.WithStack(err) |
|
| 82 | 82 |
} |
| 83 | 83 |
|
| 84 | 84 |
if err := os.Chown(sockPath, opt.UID, opt.GID); err != nil {
|
| 85 | 85 |
l.Close() |
| 86 |
- return "", nil, err |
|
| 86 |
+ return "", nil, errors.WithStack(err) |
|
| 87 | 87 |
} |
| 88 | 88 |
if err := os.Chmod(sockPath, os.FileMode(opt.Mode)); err != nil {
|
| 89 | 89 |
l.Close() |
| 90 |
- return "", nil, err |
|
| 90 |
+ return "", nil, errors.WithStack(err) |
|
| 91 | 91 |
} |
| 92 | 92 |
|
| 93 | 93 |
s := &server{caller: c}
|
| ... | ... |
@@ -102,12 +103,12 @@ func MountSSHSocket(ctx context.Context, c session.Caller, opt SocketOpt) (sockP |
| 102 | 102 |
return sockPath, func() error {
|
| 103 | 103 |
err := l.Close() |
| 104 | 104 |
os.RemoveAll(sockPath) |
| 105 |
- return err |
|
| 105 |
+ return errors.WithStack(err) |
|
| 106 | 106 |
}, nil |
| 107 | 107 |
} |
| 108 | 108 |
|
| 109 | 109 |
func CheckSSHID(ctx context.Context, c session.Caller, id string) error {
|
| 110 | 110 |
client := NewSSHClient(c.Conn()) |
| 111 | 111 |
_, err := client.CheckAgent(ctx, &CheckAgentRequest{ID: id})
|
| 112 |
- return err |
|
| 112 |
+ return errors.WithStack(err) |
|
| 113 | 113 |
} |
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"net/url" |
| 7 | 7 |
|
| 8 | 8 |
"github.com/moby/buildkit/session" |
| 9 |
+ "github.com/pkg/errors" |
|
| 9 | 10 |
"google.golang.org/grpc/metadata" |
| 10 | 11 |
) |
| 11 | 12 |
|
| ... | ... |
@@ -26,7 +27,7 @@ func New(ctx context.Context, c session.Caller, url *url.URL) (*Upload, error) {
|
| 26 | 26 |
|
| 27 | 27 |
cc, err := client.Pull(ctx) |
| 28 | 28 |
if err != nil {
|
| 29 |
- return nil, err |
|
| 29 |
+ return nil, errors.WithStack(err) |
|
| 30 | 30 |
} |
| 31 | 31 |
|
| 32 | 32 |
return &Upload{cc: cc}, nil
|
| ... | ... |
@@ -44,12 +45,12 @@ func (u *Upload) WriteTo(w io.Writer) (int, error) {
|
| 44 | 44 |
if err == io.EOF {
|
| 45 | 45 |
return n, nil |
| 46 | 46 |
} |
| 47 |
- return n, err |
|
| 47 |
+ return n, errors.WithStack(err) |
|
| 48 | 48 |
} |
| 49 | 49 |
nn, err := w.Write(bm.Data) |
| 50 | 50 |
n += nn |
| 51 | 51 |
if err != nil {
|
| 52 |
- return n, err |
|
| 52 |
+ return n, errors.WithStack(err) |
|
| 53 | 53 |
} |
| 54 | 54 |
} |
| 55 | 55 |
} |
| ... | ... |
@@ -331,7 +331,8 @@ func (e *edge) unpark(incoming []pipe.Sender, updates, allPipes []pipe.Receiver, |
| 331 | 331 |
if e.cacheMapReq == nil && (e.cacheMap == nil || len(e.cacheRecords) == 0) {
|
| 332 | 332 |
index := e.cacheMapIndex |
| 333 | 333 |
e.cacheMapReq = f.NewFuncRequest(func(ctx context.Context) (interface{}, error) {
|
| 334 |
- return e.op.CacheMap(ctx, index) |
|
| 334 |
+ cm, err := e.op.CacheMap(ctx, index) |
|
| 335 |
+ return cm, errors.Wrap(err, "failed to load cache key") |
|
| 335 | 336 |
}) |
| 336 | 337 |
cacheMapReq = true |
| 337 | 338 |
} |
| ... | ... |
@@ -798,7 +799,8 @@ func (e *edge) createInputRequests(desiredState edgeStatusType, f *pipeFactory, |
| 798 | 798 |
res := dep.result |
| 799 | 799 |
func(fn ResultBasedCacheFunc, res Result, index Index) {
|
| 800 | 800 |
dep.slowCacheReq = f.NewFuncRequest(func(ctx context.Context) (interface{}, error) {
|
| 801 |
- return e.op.CalcSlowCache(ctx, index, fn, res) |
|
| 801 |
+ v, err := e.op.CalcSlowCache(ctx, index, fn, res) |
|
| 802 |
+ return v, errors.Wrap(err, "failed to compute cache key") |
|
| 802 | 803 |
}) |
| 803 | 804 |
}(fn, res, dep.index) |
| 804 | 805 |
addedNew = true |
| ... | ... |
@@ -850,7 +852,7 @@ func (e *edge) loadCache(ctx context.Context) (interface{}, error) {
|
| 850 | 850 |
logrus.Debugf("load cache for %s with %s", e.edge.Vertex.Name(), rec.ID)
|
| 851 | 851 |
res, err := e.op.LoadCache(ctx, rec) |
| 852 | 852 |
if err != nil {
|
| 853 |
- return nil, err |
|
| 853 |
+ return nil, errors.Wrap(err, "failed to load cache") |
|
| 854 | 854 |
} |
| 855 | 855 |
|
| 856 | 856 |
return NewCachedResult(res, []ExportableCacheKey{{CacheKey: rec.key, Exporter: &exporter{k: rec.key, record: rec, edge: e}}}), nil
|
| ... | ... |
@@ -861,7 +863,7 @@ func (e *edge) execOp(ctx context.Context) (interface{}, error) {
|
| 861 | 861 |
cacheKeys, inputs := e.commitOptions() |
| 862 | 862 |
results, subExporters, err := e.op.Exec(ctx, toResultSlice(inputs)) |
| 863 | 863 |
if err != nil {
|
| 864 |
- return nil, err |
|
| 864 |
+ return nil, errors.WithStack(err) |
|
| 865 | 865 |
} |
| 866 | 866 |
|
| 867 | 867 |
index := e.edge.Index |
| ... | ... |
@@ -94,11 +94,11 @@ func (b *llbBridge) Solve(ctx context.Context, req frontend.SolveRequest) (res * |
| 94 | 94 |
|
| 95 | 95 |
edge, err := Load(req.Definition, ValidateEntitlements(ent), WithCacheSources(cms), RuntimePlatforms(b.platforms), WithValidateCaps()) |
| 96 | 96 |
if err != nil {
|
| 97 |
- return nil, err |
|
| 97 |
+ return nil, errors.Wrap(err, "failed to load LLB") |
|
| 98 | 98 |
} |
| 99 | 99 |
ref, err := b.builder.Build(ctx, edge) |
| 100 | 100 |
if err != nil {
|
| 101 |
- return nil, err |
|
| 101 |
+ return nil, errors.Wrap(err, "failed to build LLB") |
|
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 | 104 |
res = &frontend.Result{Ref: ref}
|
| ... | ... |
@@ -109,7 +109,7 @@ func (b *llbBridge) Solve(ctx context.Context, req frontend.SolveRequest) (res * |
| 109 | 109 |
} |
| 110 | 110 |
res, err = f.Solve(ctx, b, req.FrontendOpt) |
| 111 | 111 |
if err != nil {
|
| 112 |
- return nil, err |
|
| 112 |
+ return nil, errors.Wrapf(err, "failed to solve with frontend %s", req.Frontend) |
|
| 113 | 113 |
} |
| 114 | 114 |
} else {
|
| 115 | 115 |
return &frontend.Result{}, nil
|
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
"github.com/moby/buildkit/frontend" |
| 11 | 11 |
"github.com/moby/buildkit/snapshot" |
| 12 | 12 |
"github.com/moby/buildkit/solver" |
| 13 |
+ "github.com/moby/buildkit/solver/llbsolver" |
|
| 13 | 14 |
"github.com/moby/buildkit/solver/pb" |
| 14 | 15 |
"github.com/moby/buildkit/worker" |
| 15 | 16 |
digest "github.com/opencontainers/go-digest" |
| ... | ... |
@@ -25,6 +26,9 @@ type buildOp struct {
|
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 | 27 |
func NewBuildOp(v solver.Vertex, op *pb.Op_Build, b frontend.FrontendLLBBridge, _ worker.Worker) (solver.Op, error) {
|
| 28 |
+ if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
|
| 29 |
+ return nil, err |
|
| 30 |
+ } |
|
| 28 | 31 |
return &buildOp{
|
| 29 | 32 |
op: op.Build, |
| 30 | 33 |
b: b, |
| ... | ... |
@@ -60,6 +60,9 @@ type execOp struct {
|
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 | 62 |
func NewExecOp(v solver.Vertex, op *pb.Op_Exec, platform *pb.Platform, cm cache.Manager, sm *session.Manager, md *metadata.Store, exec executor.Executor, w worker.Worker) (solver.Op, error) {
|
| 63 |
+ if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
|
| 64 |
+ return nil, err |
|
| 65 |
+ } |
|
| 63 | 66 |
return &execOp{
|
| 64 | 67 |
op: op.Exec, |
| 65 | 68 |
cm: cm, |
| ... | ... |
@@ -324,7 +327,7 @@ func (e *execOp) getSSHMountable(ctx context.Context, m *pb.Mount) (cache.Mounta |
| 324 | 324 |
if m.SSHOpt.Optional {
|
| 325 | 325 |
return nil, nil |
| 326 | 326 |
} |
| 327 |
- if st, ok := status.FromError(err); ok && st.Code() == codes.Unimplemented {
|
|
| 327 |
+ if st, ok := status.FromError(errors.Cause(err)); ok && st.Code() == codes.Unimplemented {
|
|
| 328 | 328 |
return nil, errors.Errorf("no SSH key %q forwarded from the client", m.SSHOpt.ID)
|
| 329 | 329 |
} |
| 330 | 330 |
return nil, err |
| ... | ... |
@@ -35,6 +35,9 @@ type fileOp struct {
|
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 | 37 |
func NewFileOp(v solver.Vertex, op *pb.Op_File, cm cache.Manager, md *metadata.Store, w worker.Worker) (solver.Op, error) {
|
| 38 |
+ if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
|
| 39 |
+ return nil, err |
|
| 40 |
+ } |
|
| 38 | 41 |
return &fileOp{
|
| 39 | 42 |
op: op.File, |
| 40 | 43 |
md: md, |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
|
| 8 | 8 |
"github.com/moby/buildkit/session" |
| 9 | 9 |
"github.com/moby/buildkit/solver" |
| 10 |
+ "github.com/moby/buildkit/solver/llbsolver" |
|
| 10 | 11 |
"github.com/moby/buildkit/solver/pb" |
| 11 | 12 |
"github.com/moby/buildkit/source" |
| 12 | 13 |
"github.com/moby/buildkit/worker" |
| ... | ... |
@@ -26,6 +27,9 @@ type sourceOp struct {
|
| 26 | 26 |
} |
| 27 | 27 |
|
| 28 | 28 |
func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, platform *pb.Platform, sm *source.Manager, sessM *session.Manager, w worker.Worker) (solver.Op, error) {
|
| 29 |
+ if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
|
|
| 30 |
+ return nil, err |
|
| 31 |
+ } |
|
| 29 | 32 |
return &sourceOp{
|
| 30 | 33 |
op: op, |
| 31 | 34 |
sm: sm, |
| ... | ... |
@@ -188,8 +188,15 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige |
| 188 | 188 |
allOps[dgst] = &op |
| 189 | 189 |
} |
| 190 | 190 |
|
| 191 |
+ if len(allOps) < 2 {
|
|
| 192 |
+ return solver.Edge{}, errors.Errorf("invalid LLB with %d vertexes", len(allOps))
|
|
| 193 |
+ } |
|
| 194 |
+ |
|
| 191 | 195 |
lastOp := allOps[dgst] |
| 192 | 196 |
delete(allOps, dgst) |
| 197 |
+ if len(lastOp.Inputs) == 0 {
|
|
| 198 |
+ return solver.Edge{}, errors.Errorf("invalid LLB with no inputs on last vertex")
|
|
| 199 |
+ } |
|
| 193 | 200 |
dgst = lastOp.Inputs[0].Digest |
| 194 | 201 |
|
| 195 | 202 |
cache := make(map[digest.Digest]solver.Vertex) |
| ... | ... |
@@ -203,6 +210,11 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige |
| 203 | 203 |
if !ok {
|
| 204 | 204 |
return nil, errors.Errorf("invalid missing input digest %s", dgst)
|
| 205 | 205 |
} |
| 206 |
+ |
|
| 207 |
+ if err := ValidateOp(op); err != nil {
|
|
| 208 |
+ return nil, err |
|
| 209 |
+ } |
|
| 210 |
+ |
|
| 206 | 211 |
v, err := fn(dgst, op, rec) |
| 207 | 212 |
if err != nil {
|
| 208 | 213 |
return nil, err |
| ... | ... |
@@ -240,6 +252,55 @@ func llbOpName(op *pb.Op) string {
|
| 240 | 240 |
} |
| 241 | 241 |
} |
| 242 | 242 |
|
| 243 |
+func ValidateOp(op *pb.Op) error {
|
|
| 244 |
+ if op == nil {
|
|
| 245 |
+ return errors.Errorf("invalid nil op")
|
|
| 246 |
+ } |
|
| 247 |
+ |
|
| 248 |
+ switch op := op.Op.(type) {
|
|
| 249 |
+ case *pb.Op_Source: |
|
| 250 |
+ if op.Source == nil {
|
|
| 251 |
+ return errors.Errorf("invalid nil source op")
|
|
| 252 |
+ } |
|
| 253 |
+ case *pb.Op_Exec: |
|
| 254 |
+ if op.Exec == nil {
|
|
| 255 |
+ return errors.Errorf("invalid nil exec op")
|
|
| 256 |
+ } |
|
| 257 |
+ if op.Exec.Meta == nil {
|
|
| 258 |
+ return errors.Errorf("invalid exec op with no meta")
|
|
| 259 |
+ } |
|
| 260 |
+ if len(op.Exec.Meta.Args) == 0 {
|
|
| 261 |
+ return errors.Errorf("invalid exec op with no args")
|
|
| 262 |
+ } |
|
| 263 |
+ if len(op.Exec.Mounts) == 0 {
|
|
| 264 |
+ return errors.Errorf("invalid exec op with no mounts")
|
|
| 265 |
+ } |
|
| 266 |
+ |
|
| 267 |
+ isRoot := false |
|
| 268 |
+ for _, m := range op.Exec.Mounts {
|
|
| 269 |
+ if m.Dest == pb.RootMount {
|
|
| 270 |
+ isRoot = true |
|
| 271 |
+ break |
|
| 272 |
+ } |
|
| 273 |
+ } |
|
| 274 |
+ if !isRoot {
|
|
| 275 |
+ return errors.Errorf("invalid exec op with no rootfs")
|
|
| 276 |
+ } |
|
| 277 |
+ case *pb.Op_File: |
|
| 278 |
+ if op.File == nil {
|
|
| 279 |
+ return errors.Errorf("invalid nil file op")
|
|
| 280 |
+ } |
|
| 281 |
+ if len(op.File.Actions) == 0 {
|
|
| 282 |
+ return errors.Errorf("invalid file op with no actions")
|
|
| 283 |
+ } |
|
| 284 |
+ case *pb.Op_Build: |
|
| 285 |
+ if op.Build == nil {
|
|
| 286 |
+ return errors.Errorf("invalid nil build op")
|
|
| 287 |
+ } |
|
| 288 |
+ } |
|
| 289 |
+ return nil |
|
| 290 |
+} |
|
| 291 |
+ |
|
| 243 | 292 |
func fileOpName(actions []*pb.FileAction) string {
|
| 244 | 293 |
names := make([]string, 0, len(actions)) |
| 245 | 294 |
for _, action := range actions {
|