diff options
-rw-r--r-- | contrib/cirrus/lib.sh | 3 | ||||
-rw-r--r-- | docs/podman.1.md | 2 | ||||
-rw-r--r-- | docs/tutorials/podman_tutorial.md | 2 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 58 | ||||
-rw-r--r-- | libpod/info.go | 2 | ||||
-rw-r--r-- | libpod/networking_linux.go | 11 | ||||
-rw-r--r-- | libpod/oci_linux.go | 3 | ||||
-rw-r--r-- | pkg/util/utils.go | 8 |
8 files changed, 63 insertions, 26 deletions
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index 2fa91258b..4a3efb8ff 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -106,7 +106,10 @@ ircmsg() { SCRIPT="$GOSRC/$SCRIPT_BASE/podbot.py" NICK="podbot_$CIRRUS_TASK_ID" NICK="${NICK:0:15}" # Any longer will break things + set +e $SCRIPT $NICK $1 + echo "Ignoring exit($?)" + set -e } # Run sudo in directory with GOPATH set diff --git a/docs/podman.1.md b/docs/podman.1.md index 085af97ff..c66a9cf05 100644 --- a/docs/podman.1.md +++ b/docs/podman.1.md @@ -56,7 +56,7 @@ Path to the OCI compatible binary used to run containers **--storage-driver, -s**=**value** -Storage driver. The default storage driver for UID 0 is configured in /etc/containers/storage.conf (`$HOME/.config/containers/storage.conf` in rootless mode), and is *vfs* for other users. The `STORAGE_DRIVER` environment variable overrides the default. The --storage-driver specified driver overrides all. +Storage driver. The default storage driver for UID 0 is configured in /etc/containers/storage.conf (`$HOME/.config/containers/storage.conf` in rootless mode), and is *vfs* for non-root users when *fuse-overlayfs* is not available. The `STORAGE_DRIVER` environment variable overrides the default. The --storage-driver specified driver overrides all. Overriding this option will cause the *storage-opt* settings in /etc/containers/storage.conf to be ignored. The user must specify additional options via the `--storage-opt` flag. diff --git a/docs/tutorials/podman_tutorial.md b/docs/tutorials/podman_tutorial.md index 152d65a59..d48df289f 100644 --- a/docs/tutorials/podman_tutorial.md +++ b/docs/tutorials/podman_tutorial.md @@ -77,7 +77,7 @@ $ sudo curl https://raw.githubusercontent.com/containers/skopeo/master/default-p ```console $ git clone https://github.com/containernetworking/plugins.git $GOPATH/src/github.com/containernetworking/plugins $ cd $GOPATH/src/github.com/containernetworking/plugins -$ ./build.sh +$ ./build_linux.sh $ sudo mkdir -p /usr/libexec/cni $ sudo cp bin/* /usr/libexec/cni ``` diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 163cd75e7..66c7e8a04 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -57,7 +57,7 @@ func (c *Container) prepare() (err error) { networkStatus []*cnitypes.Result createNetNSErr, mountStorageErr error mountPoint string - saveNetworkStatus bool + tmpStateLock sync.Mutex ) wg.Add(2) @@ -66,17 +66,55 @@ func (c *Container) prepare() (err error) { defer wg.Done() // Set up network namespace if not already set up if c.config.CreateNetNS && c.state.NetNS == nil && !c.config.PostConfigureNetNS { - saveNetworkStatus = true netNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c) + + tmpStateLock.Lock() + defer tmpStateLock.Unlock() + + // Assign NetNS attributes to container + if createNetNSErr == nil { + c.state.NetNS = netNS + c.state.NetworkStatus = networkStatus + } } }() // Mount storage if not mounted go func() { defer wg.Done() mountPoint, mountStorageErr = c.mountStorage() + + if mountStorageErr != nil { + return + } + + tmpStateLock.Lock() + defer tmpStateLock.Unlock() + + // Finish up mountStorage + c.state.Mounted = true + c.state.Mountpoint = mountPoint + if c.state.UserNSRoot == "" { + c.state.RealMountpoint = c.state.Mountpoint + } else { + c.state.RealMountpoint = filepath.Join(c.state.UserNSRoot, "mountpoint") + } + + logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint) + }() + + defer func() { + if err != nil { + if err2 := c.cleanupNetwork(); err2 != nil { + logrus.Errorf("Error cleaning up container %s network: %v", c.ID(), err2) + } + if err2 := c.cleanupStorage(); err2 != nil { + logrus.Errorf("Error cleaning up container %s storage: %v", c.ID(), err2) + } + } }() wg.Wait() + if createNetNSErr != nil { if mountStorageErr != nil { logrus.Error(createNetNSErr) @@ -88,22 +126,6 @@ func (c *Container) prepare() (err error) { return mountStorageErr } - // Assign NetNS attributes to container - if saveNetworkStatus { - c.state.NetNS = netNS - c.state.NetworkStatus = networkStatus - } - - // Finish up mountStorage - c.state.Mounted = true - c.state.Mountpoint = mountPoint - if c.state.UserNSRoot == "" { - c.state.RealMountpoint = c.state.Mountpoint - } else { - c.state.RealMountpoint = filepath.Join(c.state.UserNSRoot, "mountpoint") - } - - logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint) // Save the container return c.save() } diff --git a/libpod/info.go b/libpod/info.go index 4cbf3f734..5d8d160c8 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/utils" "github.com/containers/storage/pkg/system" "github.com/pkg/errors" @@ -30,6 +31,7 @@ func (r *Runtime) hostInfo() (map[string]interface{}, error) { info["os"] = runtime.GOOS info["arch"] = runtime.GOARCH info["cpus"] = runtime.NumCPU() + info["rootless"] = rootless.IsRootless() mi, err := system.ReadMemInfo() if err != nil { return nil, errors.Wrapf(err, "error reading memory info") diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 863a764e2..43d0a61a4 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -64,20 +64,20 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re } }() - networkStatus := make([]*cnitypes.Result, 1) + networkStatus := make([]*cnitypes.Result, 0) for idx, r := range results { logrus.Debugf("[%d] CNI result: %v", idx, r.String()) resultCurrent, err := cnitypes.GetResult(r) if err != nil { return nil, errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.String(), err) } - networkStatus = append(ctr.state.NetworkStatus, resultCurrent) + networkStatus = append(networkStatus, resultCurrent) } // Add firewall rules to ensure the container has network access. // Will not be necessary once CNI firewall plugin merges upstream. // https://github.com/containernetworking/plugins/pull/75 - for _, netStatus := range ctr.state.NetworkStatus { + for _, netStatus := range networkStatus { firewallConf := &firewall.FirewallNetConf{ PrevResult: netStatus, } @@ -90,13 +90,16 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re } // Create and configure a new network namespace for a container -func (r *Runtime) createNetNS(ctr *Container) (ns.NetNS, []*cnitypes.Result, error) { +func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q []*cnitypes.Result, err error) { ctrNS, err := netns.NewNS() if err != nil { return nil, nil, errors.Wrapf(err, "error creating network namespace for container %s", ctr.ID()) } defer func() { if err != nil { + if err2 := netns.UnmountNS(ctrNS); err2 != nil { + logrus.Errorf("Error unmounting partially created network namespace for container %s: %v", ctr.ID(), err2) + } if err2 := ctrNS.Close(); err2 != nil { logrus.Errorf("Error closing partially created network namespace for container %s: %v", ctr.ID(), err2) } diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go index 0447670b3..e6b7cbe4f 100644 --- a/libpod/oci_linux.go +++ b/libpod/oci_linux.go @@ -74,7 +74,8 @@ func (r *OCIRuntime) createContainer(ctr *Container, cgroupParent string, restor defer wg.Done() runtime.LockOSThread() - fd, err := os.Open(fmt.Sprintf("/proc/%d/task/%d/ns/mnt", os.Getpid(), unix.Gettid())) + var fd *os.File + fd, err = os.Open(fmt.Sprintf("/proc/%d/task/%d/ns/mnt", os.Getpid(), unix.Gettid())) if err != nil { return } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 69f49e72a..3b43489b2 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -3,6 +3,7 @@ package util import ( "fmt" "os" + "os/exec" "path/filepath" "strconv" "strings" @@ -273,7 +274,12 @@ func GetRootlessStorageOpts() (storage.StoreOptions, error) { dataDir = filepath.Join(resolvedHome, ".local", "share") } opts.GraphRoot = filepath.Join(dataDir, "containers", "storage") - opts.GraphDriverName = "vfs" + if path, err := exec.LookPath("fuse-overlayfs"); err == nil { + opts.GraphDriverName = "overlay" + opts.GraphDriverOptions = []string{fmt.Sprintf("overlay.mount_program=%s", path)} + } else { + opts.GraphDriverName = "vfs" + } return opts, nil } |