diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/image/image.go | 67 | ||||
-rw-r--r-- | libpod/networking_linux.go | 30 |
2 files changed, 92 insertions, 5 deletions
diff --git a/libpod/image/image.go b/libpod/image/image.go index 72f07dad1..c5939e055 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -1212,3 +1212,70 @@ func (i *Image) newImageEvent(status events.Status) { logrus.Infof("unable to write event to %s", i.imageruntime.EventsLogFilePath) } } + +// LayerInfo keeps information of single layer +type LayerInfo struct { + // Layer ID + ID string + // Parent ID of current layer. + ParentID string + // ChildID of current layer. + // there can be multiple children in case of fork + ChildID []string + // RepoTag will have image repo names, if layer is top layer of image + RepoTags []string + // Size stores Uncompressed size of layer. + Size int64 +} + +// GetLayersMapWithImageInfo returns map of image-layers, with associated information like RepoTags, parent and list of child layers. +func GetLayersMapWithImageInfo(imageruntime *Runtime) (map[string]*LayerInfo, error) { + + // Memory allocated to store map of layers with key LayerID. + // Map will build dependency chain with ParentID and ChildID(s) + layerInfoMap := make(map[string]*LayerInfo) + + // scan all layers & fill size and parent id for each layer in layerInfoMap + layers, err := imageruntime.store.Layers() + if err != nil { + return nil, err + } + for _, layer := range layers { + _, ok := layerInfoMap[layer.ID] + if !ok { + layerInfoMap[layer.ID] = &LayerInfo{ + ID: layer.ID, + Size: layer.UncompressedSize, + ParentID: layer.Parent, + } + } else { + return nil, fmt.Errorf("detected multiple layers with the same ID %q", layer.ID) + } + } + + // scan all layers & add all childs for each layers to layerInfo + for _, layer := range layers { + _, ok := layerInfoMap[layer.ID] + if ok { + if layer.Parent != "" { + layerInfoMap[layer.Parent].ChildID = append(layerInfoMap[layer.Parent].ChildID, layer.ID) + } + } else { + return nil, fmt.Errorf("lookup error: layer-id %s, not found", layer.ID) + } + } + + // Add the Repo Tags to Top layer of each image. + imgs, err := imageruntime.store.Images() + if err != nil { + return nil, err + } + for _, img := range imgs { + e, ok := layerInfoMap[img.TopLayer] + if !ok { + return nil, fmt.Errorf("top-layer for image %s not found local store", img.ID) + } + e.RepoTags = append(e.RepoTags, img.Names...) + } + return layerInfoMap, nil +} diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 80d7d8213..d8b0cffcb 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -134,6 +134,15 @@ type slirp4netnsCmd struct { Args slirp4netnsCmdArg `json:"arguments"` } +func checkSlirpFlags(path string) (bool, bool, error) { + cmd := exec.Command(path, "--help") + out, err := cmd.CombinedOutput() + if err != nil { + return false, false, err + } + return strings.Contains(string(out), "--disable-host-loopback"), strings.Contains(string(out), "--mtu"), nil +} + // Configure the network namespace for a rootless container func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) { defer ctr.rootlessSlirpSyncR.Close() @@ -159,13 +168,24 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) { havePortMapping := len(ctr.Config().PortMappings) > 0 apiSocket := filepath.Join(r.ociRuntime.tmpDir, fmt.Sprintf("%s.net", ctr.config.ID)) - var cmd *exec.Cmd + + cmdArgs := []string{} if havePortMapping { - // if we need ports to be mapped from the host, create a API socket to use for communicating with slirp4netns. - cmd = exec.Command(path, "-c", "-e", "3", "-r", "4", "--api-socket", apiSocket, fmt.Sprintf("%d", ctr.state.PID), "tap0") - } else { - cmd = exec.Command(path, "-c", "-e", "3", "-r", "4", fmt.Sprintf("%d", ctr.state.PID), "tap0") + cmdArgs = append(cmdArgs, "--api-socket", apiSocket, fmt.Sprintf("%d", ctr.state.PID)) } + dhp, mtu, err := checkSlirpFlags(path) + if err != nil { + return errors.Wrapf(err, "error checking slirp4netns binary %s", path) + } + if dhp { + cmdArgs = append(cmdArgs, "--disable-host-loopback") + } + if mtu { + cmdArgs = append(cmdArgs, "--mtu", "65520") + } + cmdArgs = append(cmdArgs, "-c", "-e", "3", "-r", "4", fmt.Sprintf("%d", ctr.state.PID), "tap0") + + cmd := exec.Command(path, cmdArgs...) cmd.SysProcAttr = &syscall.SysProcAttr{ Setpgid: true, |