diff --git a/image.go b/image.go index c607971820..77153bb136 100644 --- a/image.go +++ b/image.go @@ -211,6 +211,25 @@ func (img *Image) getParentsSize(size int64) int64 { return parentImage.getParentsSize(size) } +// Depth returns the number of parents for a +// current image +func (img *Image) Depth() (int, error) { + var ( + count = 0 + parent = img + err error + ) + + for parent != nil { + count++ + parent, err = parent.GetParent() + if err != nil { + return -1, err + } + } + return count, nil +} + // Build an Image object from raw json data func NewImgJSON(src []byte) (*Image, error) { ret := &Image{} diff --git a/runtime.go b/runtime.go index e1ce7551ea..80e955d4a3 100644 --- a/runtime.go +++ b/runtime.go @@ -24,6 +24,9 @@ import ( "time" ) +// Set the max depth to the aufs restriction +const MaxImageDepth = 42 + var defaultDns = []string{"8.8.8.8", "8.8.4.4"} type Capabilities struct { @@ -367,6 +370,17 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin return nil, nil, err } + // We add 2 layers to the depth because the container's rw and + // init layer add to the restriction + depth, err := img.Depth() + if err != nil { + return nil, nil, err + } + + if depth+2 >= MaxImageDepth { + return nil, nil, fmt.Errorf("Cannot create container with more than %d parents", MaxImageDepth) + } + checkDeprecatedExpose := func(config *Config) bool { if config != nil { if config.PortSpecs != nil {