Merge pull request #33236 from cpuguy83/17.03.2_cherry_picks

17.03.2 cherry picks
This commit is contained in:
Sebastiaan van Stijn 2017-05-17 11:56:44 +02:00 committed by GitHub
commit 8b9c66e80d
8 changed files with 118 additions and 67 deletions

View file

@ -6,8 +6,6 @@ import (
"strings"
"time"
"golang.org/x/net/context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/cli"
@ -17,6 +15,7 @@ import (
"github.com/docker/docker/utils/templates"
"github.com/docker/go-units"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)
type infoOptions struct {
@ -66,11 +65,6 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
if info.DriverStatus != nil {
for _, pair := range info.DriverStatus {
fmt.Fprintf(dockerCli.Out(), " %s: %s\n", pair[0], pair[1])
// print a warning if devicemapper is using a loopback file
if pair[0] == "Data loop file" {
fmt.Fprintln(dockerCli.Err(), " WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.")
}
}
}
@ -228,43 +222,6 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
fmt.Fprintf(dockerCli.Out(), "Registry: %v\n", info.IndexServerAddress)
}
// Only output these warnings if the server does not support these features
if info.OSType != "windows" {
if !info.MemoryLimit {
fmt.Fprintln(dockerCli.Err(), "WARNING: No memory limit support")
}
if !info.SwapLimit {
fmt.Fprintln(dockerCli.Err(), "WARNING: No swap limit support")
}
if !info.KernelMemory {
fmt.Fprintln(dockerCli.Err(), "WARNING: No kernel memory limit support")
}
if !info.OomKillDisable {
fmt.Fprintln(dockerCli.Err(), "WARNING: No oom kill disable support")
}
if !info.CPUCfsQuota {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu cfs quota support")
}
if !info.CPUCfsPeriod {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu cfs period support")
}
if !info.CPUShares {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu shares support")
}
if !info.CPUSet {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpuset support")
}
if !info.IPv4Forwarding {
fmt.Fprintln(dockerCli.Err(), "WARNING: IPv4 forwarding is disabled")
}
if !info.BridgeNfIptables {
fmt.Fprintln(dockerCli.Err(), "WARNING: bridge-nf-call-iptables is disabled")
}
if !info.BridgeNfIP6tables {
fmt.Fprintln(dockerCli.Err(), "WARNING: bridge-nf-call-ip6tables is disabled")
}
}
if info.Labels != nil {
fmt.Fprintln(dockerCli.Out(), "Labels:")
for _, attribute := range info.Labels {
@ -317,11 +274,85 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
}
}
fmt.Fprintf(dockerCli.Out(), "Live Restore Enabled: %v\n", info.LiveRestoreEnabled)
fmt.Fprintf(dockerCli.Out(), "Live Restore Enabled: %v\n\n", info.LiveRestoreEnabled)
// Only output these warnings if the server does not support these features
if info.OSType != "windows" {
printStorageDriverWarnings(dockerCli, info)
if !info.MemoryLimit {
fmt.Fprintln(dockerCli.Err(), "WARNING: No memory limit support")
}
if !info.SwapLimit {
fmt.Fprintln(dockerCli.Err(), "WARNING: No swap limit support")
}
if !info.KernelMemory {
fmt.Fprintln(dockerCli.Err(), "WARNING: No kernel memory limit support")
}
if !info.OomKillDisable {
fmt.Fprintln(dockerCli.Err(), "WARNING: No oom kill disable support")
}
if !info.CPUCfsQuota {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu cfs quota support")
}
if !info.CPUCfsPeriod {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu cfs period support")
}
if !info.CPUShares {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpu shares support")
}
if !info.CPUSet {
fmt.Fprintln(dockerCli.Err(), "WARNING: No cpuset support")
}
if !info.IPv4Forwarding {
fmt.Fprintln(dockerCli.Err(), "WARNING: IPv4 forwarding is disabled")
}
if !info.BridgeNfIptables {
fmt.Fprintln(dockerCli.Err(), "WARNING: bridge-nf-call-iptables is disabled")
}
if !info.BridgeNfIP6tables {
fmt.Fprintln(dockerCli.Err(), "WARNING: bridge-nf-call-ip6tables is disabled")
}
}
return nil
}
func printStorageDriverWarnings(dockerCli *command.DockerCli, info types.Info) {
if info.DriverStatus == nil {
return
}
for _, pair := range info.DriverStatus {
if pair[0] == "Data loop file" {
fmt.Fprintf(dockerCli.Err(), "WARNING: %s: usage of loopback devices is strongly discouraged for production use.\n Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.\n", info.Driver)
}
if pair[0] == "Supports d_type" && pair[1] == "false" {
backingFs := getBackingFs(info)
msg := fmt.Sprintf("WARNING: %s: the backing %s filesystem is formatted without d_type support, which leads to incorrect behavior.\n", info.Driver, backingFs)
if backingFs == "xfs" {
msg += " Reformat the filesystem with ftype=1 to enable d_type support.\n"
}
msg += " Running without d_type support will not be supported in future releases."
fmt.Fprintln(dockerCli.Err(), msg)
}
}
}
func getBackingFs(info types.Info) string {
if info.DriverStatus == nil {
return ""
}
for _, pair := range info.DriverStatus {
if pair[0] == "Backing Filesystem" {
return pair[1]
}
}
return ""
}
func formatInfo(dockerCli *command.DockerCli, info types.Info, format string) error {
tmpl, err := templates.Parse(format)
if err != nil {

View file

@ -213,6 +213,8 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) {
}
}
label.Relabel(localMountPath, c.MountLabel, false)
// remount secrets ro
if err := mount.Mount("tmpfs", localMountPath, "tmpfs", "remount,ro,"+tmpfsOwnership); err != nil {
return errors.Wrap(err, "unable to remount secret dir as readonly")

View file

@ -16,7 +16,6 @@ import (
"github.com/docker/docker/container"
"github.com/docker/docker/volume"
"github.com/docker/docker/volume/drivers"
"github.com/opencontainers/runc/libcontainer/label"
)
var (
@ -195,9 +194,6 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
return err
}
if err := label.Relabel(mp.Source, container.MountLabel, false); err != nil {
return err
}
mp.Volume = v
mp.Name = v.Name()
mp.Driver = v.DriverName()

View file

@ -575,7 +575,7 @@ func (pm *Manager) Remove(name string, config *types.PluginRmConfig) error {
func getMounts(root string) ([]string, error) {
infos, err := mount.GetMounts()
if err != nil {
return nil, errors.Wrap(err, "failed to read mount table while performing recursive unmount")
return nil, errors.Wrap(err, "failed to read mount table")
}
var mounts []string

View file

@ -171,9 +171,17 @@ func (pm *Manager) upgradePlugin(p *v2.Plugin, configDigest digest.Digest, blobs
pdir := filepath.Join(pm.config.Root, p.PluginObj.ID)
orig := filepath.Join(pdir, "rootfs")
// Make sure nothing is mounted
// This could happen if the plugin was disabled with `-f` with active mounts.
// If there is anything in `orig` is still mounted, this should error out.
if err := recursiveUnmount(orig); err != nil {
return err
}
backup := orig + "-old"
if err := os.Rename(orig, backup); err != nil {
return err
return errors.Wrap(err, "error backing up plugin data before upgrade")
}
defer func() {

View file

@ -519,7 +519,11 @@ func lookupVolume(driverName, volumeName string) (volume.Volume, error) {
if err != nil {
err = errors.Cause(err)
if _, ok := err.(net.Error); ok {
return nil, errors.Wrapf(err, "error while checking if volume %q exists in driver %q", v.Name(), v.DriverName())
if v != nil {
volumeName = v.Name()
driverName = v.DriverName()
}
return nil, errors.Wrapf(err, "error while checking if volume %q exists in driver %q", volumeName, driverName)
}
// At this point, the error could be anything from the driver, such as "no such volume"
@ -542,7 +546,7 @@ func (s *VolumeStore) Remove(v volume.Volume) error {
vd, err := volumedrivers.GetDriver(v.DriverName())
if err != nil {
return &OpErr{Err: err, Name: vd.Name(), Op: "remove"}
return &OpErr{Err: err, Name: v.DriverName(), Op: "remove"}
}
logrus.Debugf("Removing volume reference: driver %s, name %s", v.DriverName(), name)

View file

@ -124,7 +124,20 @@ type MountPoint struct {
// Setup sets up a mount point by either mounting the volume if it is
// configured, or creating the source directory if supplied.
func (m *MountPoint) Setup(mountLabel string, rootUID, rootGID int) (string, error) {
func (m *MountPoint) Setup(mountLabel string, rootUID, rootGID int) (path string, err error) {
defer func() {
if err == nil {
if label.RelabelNeeded(m.Mode) {
if err = label.Relabel(m.Source, mountLabel, label.IsShared(m.Mode)); err != nil {
path = ""
err = errors.Wrapf(err, "error setting label on mount source '%s'", m.Source)
return
}
}
}
return
}()
if m.Volume != nil {
id := m.ID
if id == "" {
@ -152,11 +165,6 @@ func (m *MountPoint) Setup(mountLabel string, rootUID, rootGID int) (string, err
}
}
}
if label.RelabelNeeded(m.Mode) {
if err := label.Relabel(m.Source, mountLabel, label.IsShared(m.Mode)); err != nil {
return "", errors.Wrapf(err, "error setting label on mount source '%s'", m.Source)
}
}
return m.Source, nil
}
@ -303,10 +311,12 @@ func ParseMountSpec(cfg mounttypes.Mount, options ...func(*validateOpts)) (*Moun
}
case mounttypes.TypeBind:
mp.Source = clean(convertSlash(cfg.Source))
if cfg.BindOptions != nil {
if len(cfg.BindOptions.Propagation) > 0 {
mp.Propagation = cfg.BindOptions.Propagation
}
if cfg.BindOptions != nil && len(cfg.BindOptions.Propagation) > 0 {
mp.Propagation = cfg.BindOptions.Propagation
} else {
// If user did not specify a propagation mode, get
// default propagation mode.
mp.Propagation = DefaultPropagationMode
}
case mounttypes.TypeTmpfs:
// NOP

View file

@ -229,10 +229,10 @@ func TestParseMountSpec(t *testing.T) {
defer os.RemoveAll(testDir)
cases := []c{
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath}},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, RW: true}},
{mount.Mount{Type: mount.TypeBind, Source: testDir + string(os.PathSeparator), Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath}},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath + string(os.PathSeparator), ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath}},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: DefaultPropagationMode}},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, RW: true, Propagation: DefaultPropagationMode}},
{mount.Mount{Type: mount.TypeBind, Source: testDir + string(os.PathSeparator), Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: DefaultPropagationMode}},
{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath + string(os.PathSeparator), ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: DefaultPropagationMode}},
{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: DefaultCopyMode}},
{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath + string(os.PathSeparator)}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: DefaultCopyMode}},
}