github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/daemon/daemon_solaris.go (about)

     1  // +build solaris,cgo
     2  
     3  package daemon
     4  
     5  import (
     6  	"fmt"
     7  	"net"
     8  	"strconv"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/docker/docker/api/types"
    12  	containertypes "github.com/docker/docker/api/types/container"
    13  	"github.com/docker/docker/container"
    14  	"github.com/docker/docker/image"
    15  	"github.com/docker/docker/layer"
    16  	"github.com/docker/docker/pkg/idtools"
    17  	"github.com/docker/docker/pkg/parsers/kernel"
    18  	"github.com/docker/docker/pkg/sysinfo"
    19  	refstore "github.com/docker/docker/reference"
    20  	"github.com/docker/libnetwork"
    21  	nwconfig "github.com/docker/libnetwork/config"
    22  	"github.com/docker/libnetwork/drivers/solaris/bridge"
    23  	"github.com/docker/libnetwork/netlabel"
    24  	"github.com/docker/libnetwork/netutils"
    25  	lntypes "github.com/docker/libnetwork/types"
    26  	"github.com/opencontainers/runtime-spec/specs-go"
    27  	"github.com/opencontainers/selinux/go-selinux/label"
    28  	"github.com/pkg/errors"
    29  )
    30  
    31  //#include <zone.h>
    32  import "C"
    33  
    34  const (
    35  	defaultVirtualSwitch = "Virtual Switch"
    36  	platformSupported    = true
    37  	solarisMinCPUShares  = 1
    38  	solarisMaxCPUShares  = 65535
    39  )
    40  
    41  func getMemoryResources(config containertypes.Resources) specs.CappedMemory {
    42  	memory := specs.CappedMemory{}
    43  
    44  	if config.Memory > 0 {
    45  		memory.Physical = strconv.FormatInt(config.Memory, 10)
    46  	}
    47  
    48  	if config.MemorySwap != 0 {
    49  		memory.Swap = strconv.FormatInt(config.MemorySwap, 10)
    50  	}
    51  
    52  	return memory
    53  }
    54  
    55  func getCPUResources(config containertypes.Resources) specs.CappedCPU {
    56  	cpu := specs.CappedCPU{}
    57  
    58  	if config.CpusetCpus != "" {
    59  		cpu.Ncpus = config.CpusetCpus
    60  	}
    61  
    62  	return cpu
    63  }
    64  
    65  func (daemon *Daemon) cleanupMountsByID(id string) error {
    66  	return nil
    67  }
    68  
    69  func (daemon *Daemon) parseSecurityOpt(container *container.Container, hostConfig *containertypes.HostConfig) error {
    70  	return parseSecurityOpt(container, hostConfig)
    71  }
    72  
    73  func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
    74  	//Since config.SecurityOpt is specifically defined as a "List of string values to
    75  	//customize labels for MLs systems, such as SELinux"
    76  	//until we figure out how to map to Trusted Extensions
    77  	//this is being disabled for now on Solaris
    78  	var (
    79  		labelOpts []string
    80  		err       error
    81  	)
    82  
    83  	if len(config.SecurityOpt) > 0 {
    84  		return errors.New("Security options are not supported on Solaris")
    85  	}
    86  
    87  	container.ProcessLabel, container.MountLabel, err = label.InitLabels(labelOpts)
    88  	return err
    89  }
    90  
    91  func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) {
    92  	return nil, nil, nil
    93  }
    94  
    95  func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
    96  	return nil
    97  }
    98  
    99  func (daemon *Daemon) getLayerInit() func(string) error {
   100  	return nil
   101  }
   102  
   103  func checkKernel() error {
   104  	// solaris can rely upon checkSystem() below, we don't skew kernel versions
   105  	return nil
   106  }
   107  
   108  func (daemon *Daemon) getCgroupDriver() string {
   109  	return ""
   110  }
   111  
   112  func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConfig, adjustCPUShares bool) error {
   113  	if hostConfig.CPUShares < 0 {
   114  		logrus.Warnf("Changing requested CPUShares of %d to minimum allowed of %d", hostConfig.CPUShares, solarisMinCPUShares)
   115  		hostConfig.CPUShares = solarisMinCPUShares
   116  	} else if hostConfig.CPUShares > solarisMaxCPUShares {
   117  		logrus.Warnf("Changing requested CPUShares of %d to maximum allowed of %d", hostConfig.CPUShares, solarisMaxCPUShares)
   118  		hostConfig.CPUShares = solarisMaxCPUShares
   119  	}
   120  
   121  	if hostConfig.Memory > 0 && hostConfig.MemorySwap == 0 {
   122  		// By default, MemorySwap is set to twice the size of Memory.
   123  		hostConfig.MemorySwap = hostConfig.Memory * 2
   124  	}
   125  
   126  	if hostConfig.ShmSize != 0 {
   127  		hostConfig.ShmSize = container.DefaultSHMSize
   128  	}
   129  	if hostConfig.OomKillDisable == nil {
   130  		defaultOomKillDisable := false
   131  		hostConfig.OomKillDisable = &defaultOomKillDisable
   132  	}
   133  
   134  	return nil
   135  }
   136  
   137  // UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
   138  func UsingSystemd(config *Config) bool {
   139  	return false
   140  }
   141  
   142  // verifyPlatformContainerSettings performs platform-specific validation of the
   143  // hostconfig and config structures.
   144  func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
   145  	warnings := []string{}
   146  	sysInfo := sysinfo.New(true)
   147  	// NOTE: We do not enforce a minimum value for swap limits for zones on Solaris and
   148  	// therefore we will not do that for Docker container either.
   149  	if hostConfig.Memory > 0 && !sysInfo.MemoryLimit {
   150  		warnings = append(warnings, "Your kernel does not support memory limit capabilities. Limitation discarded.")
   151  		logrus.Warnf("Your kernel does not support memory limit capabilities. Limitation discarded.")
   152  		hostConfig.Memory = 0
   153  		hostConfig.MemorySwap = -1
   154  	}
   155  	if hostConfig.Memory > 0 && hostConfig.MemorySwap != -1 && !sysInfo.SwapLimit {
   156  		warnings = append(warnings, "Your kernel does not support swap limit capabilities, memory limited without swap.")
   157  		logrus.Warnf("Your kernel does not support swap limit capabilities, memory limited without swap.")
   158  		hostConfig.MemorySwap = -1
   159  	}
   160  	if hostConfig.Memory > 0 && hostConfig.MemorySwap > 0 && hostConfig.MemorySwap < hostConfig.Memory {
   161  		return warnings, fmt.Errorf("Minimum memoryswap limit should be larger than memory limit, see usage.")
   162  	}
   163  	// Solaris NOTE: We allow and encourage setting the swap without setting the memory limit.
   164  
   165  	if hostConfig.MemorySwappiness != nil && *hostConfig.MemorySwappiness != -1 && !sysInfo.MemorySwappiness {
   166  		warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, memory swappiness discarded.")
   167  		logrus.Warnf("Your kernel does not support memory swappiness capabilities, memory swappiness discarded.")
   168  		hostConfig.MemorySwappiness = nil
   169  	}
   170  	if hostConfig.MemoryReservation > 0 && !sysInfo.MemoryReservation {
   171  		warnings = append(warnings, "Your kernel does not support memory soft limit capabilities. Limitation discarded.")
   172  		logrus.Warnf("Your kernel does not support memory soft limit capabilities. Limitation discarded.")
   173  		hostConfig.MemoryReservation = 0
   174  	}
   175  	if hostConfig.Memory > 0 && hostConfig.MemoryReservation > 0 && hostConfig.Memory < hostConfig.MemoryReservation {
   176  		return warnings, fmt.Errorf("Minimum memory limit should be larger than memory reservation limit, see usage.")
   177  	}
   178  	if hostConfig.KernelMemory > 0 && !sysInfo.KernelMemory {
   179  		warnings = append(warnings, "Your kernel does not support kernel memory limit capabilities. Limitation discarded.")
   180  		logrus.Warnf("Your kernel does not support kernel memory limit capabilities. Limitation discarded.")
   181  		hostConfig.KernelMemory = 0
   182  	}
   183  	if hostConfig.CPUShares != 0 && !sysInfo.CPUShares {
   184  		warnings = append(warnings, "Your kernel does not support CPU shares. Shares discarded.")
   185  		logrus.Warnf("Your kernel does not support CPU shares. Shares discarded.")
   186  		hostConfig.CPUShares = 0
   187  	}
   188  	if hostConfig.CPUShares < 0 {
   189  		warnings = append(warnings, "Invalid CPUShares value. Must be positive. Discarding.")
   190  		logrus.Warnf("Invalid CPUShares value. Must be positive. Discarding.")
   191  		hostConfig.CPUQuota = 0
   192  	}
   193  	if hostConfig.CPUShares > 0 && !sysinfo.IsCPUSharesAvailable() {
   194  		warnings = append(warnings, "Global zone default scheduling class not FSS. Discarding shares.")
   195  		logrus.Warnf("Global zone default scheduling class not FSS. Discarding shares.")
   196  		hostConfig.CPUShares = 0
   197  	}
   198  
   199  	// Solaris NOTE: Linux does not do negative checking for CPUShares and Quota here. But it makes sense to.
   200  	if hostConfig.CPUPeriod > 0 && !sysInfo.CPUCfsPeriod {
   201  		warnings = append(warnings, "Your kernel does not support CPU cfs period. Period discarded.")
   202  		logrus.Warnf("Your kernel does not support CPU cfs period. Period discarded.")
   203  		if hostConfig.CPUQuota > 0 {
   204  			warnings = append(warnings, "Quota will be applied on default period, not period specified.")
   205  			logrus.Warnf("Quota will be applied on default period, not period specified.")
   206  		}
   207  		hostConfig.CPUPeriod = 0
   208  	}
   209  	if hostConfig.CPUQuota != 0 && !sysInfo.CPUCfsQuota {
   210  		warnings = append(warnings, "Your kernel does not support CPU cfs quota. Quota discarded.")
   211  		logrus.Warnf("Your kernel does not support CPU cfs quota. Quota discarded.")
   212  		hostConfig.CPUQuota = 0
   213  	}
   214  	if hostConfig.CPUQuota < 0 {
   215  		warnings = append(warnings, "Invalid CPUQuota value. Must be positive. Discarding.")
   216  		logrus.Warnf("Invalid CPUQuota value. Must be positive. Discarding.")
   217  		hostConfig.CPUQuota = 0
   218  	}
   219  	if (hostConfig.CpusetCpus != "" || hostConfig.CpusetMems != "") && !sysInfo.Cpuset {
   220  		warnings = append(warnings, "Your kernel does not support cpuset. Cpuset discarded.")
   221  		logrus.Warnf("Your kernel does not support cpuset. Cpuset discarded.")
   222  		hostConfig.CpusetCpus = ""
   223  		hostConfig.CpusetMems = ""
   224  	}
   225  	cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(hostConfig.CpusetCpus)
   226  	if err != nil {
   227  		return warnings, fmt.Errorf("Invalid value %s for cpuset cpus.", hostConfig.CpusetCpus)
   228  	}
   229  	if !cpusAvailable {
   230  		return warnings, fmt.Errorf("Requested CPUs are not available - requested %s, available: %s.", hostConfig.CpusetCpus, sysInfo.Cpus)
   231  	}
   232  	memsAvailable, err := sysInfo.IsCpusetMemsAvailable(hostConfig.CpusetMems)
   233  	if err != nil {
   234  		return warnings, fmt.Errorf("Invalid value %s for cpuset mems.", hostConfig.CpusetMems)
   235  	}
   236  	if !memsAvailable {
   237  		return warnings, fmt.Errorf("Requested memory nodes are not available - requested %s, available: %s.", hostConfig.CpusetMems, sysInfo.Mems)
   238  	}
   239  	if hostConfig.BlkioWeight > 0 && !sysInfo.BlkioWeight {
   240  		warnings = append(warnings, "Your kernel does not support Block I/O weight. Weight discarded.")
   241  		logrus.Warnf("Your kernel does not support Block I/O weight. Weight discarded.")
   242  		hostConfig.BlkioWeight = 0
   243  	}
   244  	if hostConfig.OomKillDisable != nil && !sysInfo.OomKillDisable {
   245  		*hostConfig.OomKillDisable = false
   246  		// Don't warn; this is the default setting but only applicable to Linux
   247  	}
   248  
   249  	if sysInfo.IPv4ForwardingDisabled {
   250  		warnings = append(warnings, "IPv4 forwarding is disabled. Networking will not work.")
   251  		logrus.Warnf("IPv4 forwarding is disabled. Networking will not work")
   252  	}
   253  
   254  	// Solaris NOTE: We do not allow setting Linux specific options, so check and warn for all of them.
   255  
   256  	if hostConfig.CapAdd != nil || hostConfig.CapDrop != nil {
   257  		warnings = append(warnings, "Adding or dropping kernel capabilities unsupported on Solaris.Discarding capabilities lists.")
   258  		logrus.Warnf("Adding or dropping kernel capabilities unsupported on Solaris.Discarding capabilities lists.")
   259  		hostConfig.CapAdd = nil
   260  		hostConfig.CapDrop = nil
   261  	}
   262  
   263  	if hostConfig.GroupAdd != nil {
   264  		warnings = append(warnings, "Additional groups unsupported on Solaris.Discarding groups lists.")
   265  		logrus.Warnf("Additional groups unsupported on Solaris.Discarding groups lists.")
   266  		hostConfig.GroupAdd = nil
   267  	}
   268  
   269  	if hostConfig.IpcMode != "" {
   270  		warnings = append(warnings, "IPC namespace assignment unsupported on Solaris.Discarding IPC setting.")
   271  		logrus.Warnf("IPC namespace assignment unsupported on Solaris.Discarding IPC setting.")
   272  		hostConfig.IpcMode = ""
   273  	}
   274  
   275  	if hostConfig.PidMode != "" {
   276  		warnings = append(warnings, "PID namespace setting  unsupported on Solaris. Running container in host PID namespace.")
   277  		logrus.Warnf("PID namespace setting  unsupported on Solaris. Running container in host PID namespace.")
   278  		hostConfig.PidMode = ""
   279  	}
   280  
   281  	if hostConfig.Privileged {
   282  		warnings = append(warnings, "Privileged mode unsupported on Solaris. Discarding privileged mode setting.")
   283  		logrus.Warnf("Privileged mode unsupported on Solaris. Discarding privileged mode setting.")
   284  		hostConfig.Privileged = false
   285  	}
   286  
   287  	if hostConfig.UTSMode != "" {
   288  		warnings = append(warnings, "UTS namespace assignment unsupported on Solaris.Discarding UTS setting.")
   289  		logrus.Warnf("UTS namespace assignment unsupported on Solaris.Discarding UTS setting.")
   290  		hostConfig.UTSMode = ""
   291  	}
   292  
   293  	if hostConfig.CgroupParent != "" {
   294  		warnings = append(warnings, "Specifying Cgroup parent unsupported on Solaris. Discarding cgroup parent setting.")
   295  		logrus.Warnf("Specifying Cgroup parent unsupported on Solaris. Discarding cgroup parent setting.")
   296  		hostConfig.CgroupParent = ""
   297  	}
   298  
   299  	if hostConfig.Ulimits != nil {
   300  		warnings = append(warnings, "Specifying ulimits unsupported on Solaris. Discarding ulimits setting.")
   301  		logrus.Warnf("Specifying ulimits unsupported on Solaris. Discarding ulimits setting.")
   302  		hostConfig.Ulimits = nil
   303  	}
   304  
   305  	return warnings, nil
   306  }
   307  
   308  // reloadPlatform updates configuration with platform specific options
   309  // and updates the passed attributes
   310  func (daemon *Daemon) reloadPlatform(config *Config, attributes map[string]string) {
   311  }
   312  
   313  // verifyDaemonSettings performs validation of daemon config struct
   314  func verifyDaemonSettings(config *Config) error {
   315  
   316  	if config.DefaultRuntime == "" {
   317  		config.DefaultRuntime = stockRuntimeName
   318  	}
   319  	if config.Runtimes == nil {
   320  		config.Runtimes = make(map[string]types.Runtime)
   321  	}
   322  	stockRuntimeOpts := []string{}
   323  	config.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary, Args: stockRuntimeOpts}
   324  
   325  	// checkSystem validates platform-specific requirements
   326  	return nil
   327  }
   328  
   329  func checkSystem() error {
   330  	// check OS version for compatibility, ensure running in global zone
   331  	var err error
   332  	var id C.zoneid_t
   333  
   334  	if id, err = C.getzoneid(); err != nil {
   335  		return fmt.Errorf("Exiting. Error getting zone id: %+v", err)
   336  	}
   337  	if int(id) != 0 {
   338  		return fmt.Errorf("Exiting because the Docker daemon is not running in the global zone")
   339  	}
   340  
   341  	v, err := kernel.GetKernelVersion()
   342  	if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 5, Major: 12, Minor: 0}) < 0 {
   343  		return fmt.Errorf("Your Solaris kernel version: %s doesn't support Docker. Please upgrade to 5.12.0", v.String())
   344  	}
   345  	return err
   346  }
   347  
   348  // configureMaxThreads sets the Go runtime max threads threshold
   349  // which is 90% of the kernel setting from /proc/sys/kernel/threads-max
   350  func configureMaxThreads(config *Config) error {
   351  	return nil
   352  }
   353  
   354  // configureKernelSecuritySupport configures and validate security support for the kernel
   355  func configureKernelSecuritySupport(config *Config, driverName string) error {
   356  	return nil
   357  }
   358  
   359  func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
   360  	netOptions, err := daemon.networkOptions(config, daemon.PluginStore, activeSandboxes)
   361  	if err != nil {
   362  		return nil, err
   363  	}
   364  
   365  	controller, err := libnetwork.New(netOptions...)
   366  	if err != nil {
   367  		return nil, fmt.Errorf("error obtaining controller instance: %v", err)
   368  	}
   369  
   370  	// Initialize default network on "null"
   371  	if _, err := controller.NewNetwork("null", "none", "", libnetwork.NetworkOptionPersist(false)); err != nil {
   372  		return nil, fmt.Errorf("Error creating default 'null' network: %v", err)
   373  	}
   374  
   375  	if !config.DisableBridge {
   376  		// Initialize default driver "bridge"
   377  		if err := initBridgeDriver(controller, config); err != nil {
   378  			return nil, err
   379  		}
   380  	}
   381  
   382  	return controller, nil
   383  }
   384  
   385  func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error {
   386  	if n, err := controller.NetworkByName("bridge"); err == nil {
   387  		if err = n.Delete(); err != nil {
   388  			return fmt.Errorf("could not delete the default bridge network: %v", err)
   389  		}
   390  	}
   391  
   392  	bridgeName := bridge.DefaultBridgeName
   393  	if config.bridgeConfig.Iface != "" {
   394  		bridgeName = config.bridgeConfig.Iface
   395  	}
   396  	netOption := map[string]string{
   397  		bridge.BridgeName:    bridgeName,
   398  		bridge.DefaultBridge: strconv.FormatBool(true),
   399  		netlabel.DriverMTU:   strconv.Itoa(config.Mtu),
   400  		bridge.EnableICC:     strconv.FormatBool(config.bridgeConfig.InterContainerCommunication),
   401  	}
   402  
   403  	// --ip processing
   404  	if config.bridgeConfig.DefaultIP != nil {
   405  		netOption[bridge.DefaultBindingIP] = config.bridgeConfig.DefaultIP.String()
   406  	}
   407  
   408  	var ipamV4Conf *libnetwork.IpamConf
   409  
   410  	ipamV4Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)}
   411  
   412  	nwList, _, err := netutils.ElectInterfaceAddresses(bridgeName)
   413  	if err != nil {
   414  		return errors.Wrap(err, "list bridge addresses failed")
   415  	}
   416  
   417  	nw := nwList[0]
   418  	if len(nwList) > 1 && config.bridgeConfig.FixedCIDR != "" {
   419  		_, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR)
   420  		if err != nil {
   421  			return errors.Wrap(err, "parse CIDR failed")
   422  		}
   423  		// Iterate through in case there are multiple addresses for the bridge
   424  		for _, entry := range nwList {
   425  			if fCIDR.Contains(entry.IP) {
   426  				nw = entry
   427  				break
   428  			}
   429  		}
   430  	}
   431  
   432  	ipamV4Conf.PreferredPool = lntypes.GetIPNetCanonical(nw).String()
   433  	hip, _ := lntypes.GetHostPartIP(nw.IP, nw.Mask)
   434  	if hip.IsGlobalUnicast() {
   435  		ipamV4Conf.Gateway = nw.IP.String()
   436  	}
   437  
   438  	if config.bridgeConfig.IP != "" {
   439  		ipamV4Conf.PreferredPool = config.bridgeConfig.IP
   440  		ip, _, err := net.ParseCIDR(config.bridgeConfig.IP)
   441  		if err != nil {
   442  			return err
   443  		}
   444  		ipamV4Conf.Gateway = ip.String()
   445  	} else if bridgeName == bridge.DefaultBridgeName && ipamV4Conf.PreferredPool != "" {
   446  		logrus.Infof("Default bridge (%s) is assigned with an IP address %s. Daemon option --bip can be used to set a preferred IP address", bridgeName, ipamV4Conf.PreferredPool)
   447  	}
   448  
   449  	if config.bridgeConfig.FixedCIDR != "" {
   450  		_, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR)
   451  		if err != nil {
   452  			return err
   453  		}
   454  
   455  		ipamV4Conf.SubPool = fCIDR.String()
   456  	}
   457  
   458  	if config.bridgeConfig.DefaultGatewayIPv4 != nil {
   459  		ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.bridgeConfig.DefaultGatewayIPv4.String()
   460  	}
   461  
   462  	v4Conf := []*libnetwork.IpamConf{ipamV4Conf}
   463  	v6Conf := []*libnetwork.IpamConf{}
   464  
   465  	// Initialize default network on "bridge" with the same name
   466  	_, err = controller.NewNetwork("bridge", "bridge", "",
   467  		libnetwork.NetworkOptionDriverOpts(netOption),
   468  		libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil),
   469  		libnetwork.NetworkOptionDeferIPv6Alloc(false))
   470  	if err != nil {
   471  		return fmt.Errorf("Error creating default 'bridge' network: %v", err)
   472  	}
   473  	return nil
   474  }
   475  
   476  // registerLinks sets up links between containers and writes the
   477  // configuration out for persistence.
   478  func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error {
   479  	return nil
   480  }
   481  
   482  func (daemon *Daemon) cleanupMounts() error {
   483  	return nil
   484  }
   485  
   486  // conditionalMountOnStart is a platform specific helper function during the
   487  // container start to call mount.
   488  func (daemon *Daemon) conditionalMountOnStart(container *container.Container) error {
   489  	return daemon.Mount(container)
   490  }
   491  
   492  // conditionalUnmountOnCleanup is a platform specific helper function called
   493  // during the cleanup of a container to unmount.
   494  func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error {
   495  	return daemon.Unmount(container)
   496  }
   497  
   498  func restoreCustomImage(is image.Store, ls layer.Store, rs refstore.Store) error {
   499  	// Solaris has no custom images to register
   500  	return nil
   501  }
   502  
   503  func driverOptions(config *Config) []nwconfig.Option {
   504  	return []nwconfig.Option{}
   505  }
   506  
   507  func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
   508  	return nil, nil
   509  }
   510  
   511  // setDefaultIsolation determine the default isolation mode for the
   512  // daemon to run in. This is only applicable on Windows
   513  func (daemon *Daemon) setDefaultIsolation() error {
   514  	return nil
   515  }
   516  
   517  func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
   518  	return types.RootFS{}
   519  }
   520  
   521  func setupDaemonProcess(config *Config) error {
   522  	return nil
   523  }
   524  
   525  func (daemon *Daemon) setupSeccompProfile() error {
   526  	return nil
   527  }