2016-03-25 19:38:00 -04:00
// +build solaris,cgo
package daemon
import (
"fmt"
2016-06-07 03:45:21 -04:00
"net"
"strconv"
2016-03-25 19:38:00 -04:00
2016-09-06 14:18:12 -04:00
"github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container"
2016-03-25 19:38:00 -04:00
"github.com/docker/docker/container"
2017-08-09 14:58:31 -04:00
"github.com/docker/docker/daemon/config"
2016-03-25 19:38:00 -04:00
"github.com/docker/docker/image"
2017-08-03 20:22:00 -04:00
"github.com/docker/docker/pkg/containerfs"
2017-05-31 20:11:42 -04:00
"github.com/docker/docker/pkg/fileutils"
2016-03-25 19:38:00 -04:00
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/parsers/kernel"
2016-06-07 03:45:21 -04:00
"github.com/docker/docker/pkg/sysinfo"
2016-03-25 19:38:00 -04:00
"github.com/docker/libnetwork"
nwconfig "github.com/docker/libnetwork/config"
2016-06-07 03:45:21 -04:00
"github.com/docker/libnetwork/drivers/solaris/bridge"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
lntypes "github.com/docker/libnetwork/types"
2017-08-21 17:51:45 -04:00
specs "github.com/opencontainers/runtime-spec/specs-go"
2017-04-18 09:26:36 -04:00
"github.com/opencontainers/selinux/go-selinux/label"
2016-06-07 03:45:21 -04:00
"github.com/pkg/errors"
2017-07-26 17:42:13 -04:00
"github.com/sirupsen/logrus"
2016-03-25 19:38:00 -04:00
)
//#include <zone.h>
import "C"
const (
2017-08-21 17:51:45 -04:00
platformSupported = true
solarisMinCPUShares = 1
solarisMaxCPUShares = 65535
2016-03-25 19:38:00 -04:00
)
2016-06-07 03:45:21 -04:00
func getMemoryResources ( config containertypes . Resources ) specs . CappedMemory {
2017-08-01 11:51:24 -04:00
memory := specs . CappedMemory {
DisableOOMKiller : config . OomKillDisable ,
}
2016-06-07 03:45:21 -04:00
if config . Memory > 0 {
memory . Physical = strconv . FormatInt ( config . Memory , 10 )
}
if config . MemorySwap != 0 {
memory . Swap = strconv . FormatInt ( config . MemorySwap , 10 )
}
return memory
}
func getCPUResources ( config containertypes . Resources ) specs . CappedCPU {
cpu := specs . CappedCPU { }
if config . CpusetCpus != "" {
cpu . Ncpus = config . CpusetCpus
}
return cpu
}
2016-03-25 19:38:00 -04:00
func ( daemon * Daemon ) cleanupMountsByID ( id string ) error {
return nil
}
2017-01-08 20:22:05 -05:00
func ( daemon * Daemon ) parseSecurityOpt ( container * container . Container , hostConfig * containertypes . HostConfig ) error {
return parseSecurityOpt ( container , hostConfig )
}
2016-03-25 19:38:00 -04:00
func parseSecurityOpt ( container * container . Container , config * containertypes . HostConfig ) error {
2017-08-09 14:58:31 -04:00
//Since hostConfig.SecurityOpt is specifically defined as a "List of string values to
2016-06-07 03:45:21 -04:00
//customize labels for MLs systems, such as SELinux"
//until we figure out how to map to Trusted Extensions
//this is being disabled for now on Solaris
var (
labelOpts [ ] string
err error
)
if len ( config . SecurityOpt ) > 0 {
return errors . New ( "Security options are not supported on Solaris" )
}
container . ProcessLabel , container . MountLabel , err = label . InitLabels ( labelOpts )
return err
2016-03-25 19:38:00 -04:00
}
2017-08-09 14:58:31 -04:00
func setupRemappedRoot ( config * config . Config ) ( * idtools . IDMappings , error ) {
return nil , nil
2016-03-25 19:38:00 -04:00
}
2017-08-09 14:58:31 -04:00
func setupDaemonRoot ( config * config . Config , rootDir string , rootIDs idtools . IDPair ) error {
2016-03-25 19:38:00 -04:00
return nil
}
2017-08-03 20:22:00 -04:00
func ( daemon * Daemon ) getLayerInit ( ) func ( containerfs . ContainerFS ) error {
2016-09-26 16:05:28 -04:00
return nil
}
2016-03-25 19:38:00 -04:00
func checkKernel ( ) error {
// solaris can rely upon checkSystem() below, we don't skew kernel versions
return nil
}
func ( daemon * Daemon ) getCgroupDriver ( ) string {
return ""
}
func ( daemon * Daemon ) adaptContainerSettings ( hostConfig * containertypes . HostConfig , adjustCPUShares bool ) error {
2016-06-07 03:45:21 -04:00
if hostConfig . CPUShares < 0 {
logrus . Warnf ( "Changing requested CPUShares of %d to minimum allowed of %d" , hostConfig . CPUShares , solarisMinCPUShares )
hostConfig . CPUShares = solarisMinCPUShares
} else if hostConfig . CPUShares > solarisMaxCPUShares {
logrus . Warnf ( "Changing requested CPUShares of %d to maximum allowed of %d" , hostConfig . CPUShares , solarisMaxCPUShares )
hostConfig . CPUShares = solarisMaxCPUShares
}
if hostConfig . Memory > 0 && hostConfig . MemorySwap == 0 {
// By default, MemorySwap is set to twice the size of Memory.
hostConfig . MemorySwap = hostConfig . Memory * 2
}
if hostConfig . ShmSize != 0 {
hostConfig . ShmSize = container . DefaultSHMSize
}
if hostConfig . OomKillDisable == nil {
defaultOomKillDisable := false
hostConfig . OomKillDisable = & defaultOomKillDisable
}
2016-03-25 19:38:00 -04:00
return nil
}
2016-06-07 03:45:21 -04:00
// UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
2017-08-09 14:58:31 -04:00
func UsingSystemd ( config * config . Config ) bool {
2016-06-07 03:45:21 -04:00
return false
}
2016-03-25 19:38:00 -04:00
// verifyPlatformContainerSettings performs platform-specific validation of the
// hostconfig and config structures.
func verifyPlatformContainerSettings ( daemon * Daemon , hostConfig * containertypes . HostConfig , config * containertypes . Config , update bool ) ( [ ] string , error ) {
2017-06-30 13:34:40 -04:00
fixMemorySwappiness ( resources )
2016-03-25 19:38:00 -04:00
warnings := [ ] string { }
2016-06-07 03:45:21 -04:00
sysInfo := sysinfo . New ( true )
// NOTE: We do not enforce a minimum value for swap limits for zones on Solaris and
// therefore we will not do that for Docker container either.
if hostConfig . Memory > 0 && ! sysInfo . MemoryLimit {
warnings = append ( warnings , "Your kernel does not support memory limit capabilities. Limitation discarded." )
logrus . Warnf ( "Your kernel does not support memory limit capabilities. Limitation discarded." )
hostConfig . Memory = 0
hostConfig . MemorySwap = - 1
}
if hostConfig . Memory > 0 && hostConfig . MemorySwap != - 1 && ! sysInfo . SwapLimit {
warnings = append ( warnings , "Your kernel does not support swap limit capabilities, memory limited without swap." )
logrus . Warnf ( "Your kernel does not support swap limit capabilities, memory limited without swap." )
hostConfig . MemorySwap = - 1
}
if hostConfig . Memory > 0 && hostConfig . MemorySwap > 0 && hostConfig . MemorySwap < hostConfig . Memory {
return warnings , fmt . Errorf ( "Minimum memoryswap limit should be larger than memory limit, see usage." )
}
// Solaris NOTE: We allow and encourage setting the swap without setting the memory limit.
2017-06-30 13:34:40 -04:00
if hostConfig . MemorySwappiness != nil && ! sysInfo . MemorySwappiness {
2016-06-07 03:45:21 -04:00
warnings = append ( warnings , "Your kernel does not support memory swappiness capabilities, memory swappiness discarded." )
logrus . Warnf ( "Your kernel does not support memory swappiness capabilities, memory swappiness discarded." )
hostConfig . MemorySwappiness = nil
}
if hostConfig . MemoryReservation > 0 && ! sysInfo . MemoryReservation {
warnings = append ( warnings , "Your kernel does not support memory soft limit capabilities. Limitation discarded." )
logrus . Warnf ( "Your kernel does not support memory soft limit capabilities. Limitation discarded." )
hostConfig . MemoryReservation = 0
}
if hostConfig . Memory > 0 && hostConfig . MemoryReservation > 0 && hostConfig . Memory < hostConfig . MemoryReservation {
return warnings , fmt . Errorf ( "Minimum memory limit should be larger than memory reservation limit, see usage." )
}
if hostConfig . KernelMemory > 0 && ! sysInfo . KernelMemory {
warnings = append ( warnings , "Your kernel does not support kernel memory limit capabilities. Limitation discarded." )
logrus . Warnf ( "Your kernel does not support kernel memory limit capabilities. Limitation discarded." )
hostConfig . KernelMemory = 0
}
if hostConfig . CPUShares != 0 && ! sysInfo . CPUShares {
warnings = append ( warnings , "Your kernel does not support CPU shares. Shares discarded." )
logrus . Warnf ( "Your kernel does not support CPU shares. Shares discarded." )
hostConfig . CPUShares = 0
}
if hostConfig . CPUShares < 0 {
warnings = append ( warnings , "Invalid CPUShares value. Must be positive. Discarding." )
logrus . Warnf ( "Invalid CPUShares value. Must be positive. Discarding." )
hostConfig . CPUQuota = 0
}
if hostConfig . CPUShares > 0 && ! sysinfo . IsCPUSharesAvailable ( ) {
warnings = append ( warnings , "Global zone default scheduling class not FSS. Discarding shares." )
logrus . Warnf ( "Global zone default scheduling class not FSS. Discarding shares." )
hostConfig . CPUShares = 0
}
// Solaris NOTE: Linux does not do negative checking for CPUShares and Quota here. But it makes sense to.
if hostConfig . CPUPeriod > 0 && ! sysInfo . CPUCfsPeriod {
warnings = append ( warnings , "Your kernel does not support CPU cfs period. Period discarded." )
logrus . Warnf ( "Your kernel does not support CPU cfs period. Period discarded." )
if hostConfig . CPUQuota > 0 {
warnings = append ( warnings , "Quota will be applied on default period, not period specified." )
logrus . Warnf ( "Quota will be applied on default period, not period specified." )
}
hostConfig . CPUPeriod = 0
}
if hostConfig . CPUQuota != 0 && ! sysInfo . CPUCfsQuota {
warnings = append ( warnings , "Your kernel does not support CPU cfs quota. Quota discarded." )
logrus . Warnf ( "Your kernel does not support CPU cfs quota. Quota discarded." )
hostConfig . CPUQuota = 0
}
if hostConfig . CPUQuota < 0 {
warnings = append ( warnings , "Invalid CPUQuota value. Must be positive. Discarding." )
logrus . Warnf ( "Invalid CPUQuota value. Must be positive. Discarding." )
hostConfig . CPUQuota = 0
}
if ( hostConfig . CpusetCpus != "" || hostConfig . CpusetMems != "" ) && ! sysInfo . Cpuset {
warnings = append ( warnings , "Your kernel does not support cpuset. Cpuset discarded." )
logrus . Warnf ( "Your kernel does not support cpuset. Cpuset discarded." )
hostConfig . CpusetCpus = ""
hostConfig . CpusetMems = ""
}
cpusAvailable , err := sysInfo . IsCpusetCpusAvailable ( hostConfig . CpusetCpus )
if err != nil {
return warnings , fmt . Errorf ( "Invalid value %s for cpuset cpus." , hostConfig . CpusetCpus )
}
if ! cpusAvailable {
return warnings , fmt . Errorf ( "Requested CPUs are not available - requested %s, available: %s." , hostConfig . CpusetCpus , sysInfo . Cpus )
}
memsAvailable , err := sysInfo . IsCpusetMemsAvailable ( hostConfig . CpusetMems )
if err != nil {
return warnings , fmt . Errorf ( "Invalid value %s for cpuset mems." , hostConfig . CpusetMems )
}
if ! memsAvailable {
return warnings , fmt . Errorf ( "Requested memory nodes are not available - requested %s, available: %s." , hostConfig . CpusetMems , sysInfo . Mems )
}
if hostConfig . BlkioWeight > 0 && ! sysInfo . BlkioWeight {
warnings = append ( warnings , "Your kernel does not support Block I/O weight. Weight discarded." )
logrus . Warnf ( "Your kernel does not support Block I/O weight. Weight discarded." )
hostConfig . BlkioWeight = 0
}
if hostConfig . OomKillDisable != nil && ! sysInfo . OomKillDisable {
* hostConfig . OomKillDisable = false
// Don't warn; this is the default setting but only applicable to Linux
}
if sysInfo . IPv4ForwardingDisabled {
warnings = append ( warnings , "IPv4 forwarding is disabled. Networking will not work." )
logrus . Warnf ( "IPv4 forwarding is disabled. Networking will not work" )
}
// Solaris NOTE: We do not allow setting Linux specific options, so check and warn for all of them.
if hostConfig . CapAdd != nil || hostConfig . CapDrop != nil {
warnings = append ( warnings , "Adding or dropping kernel capabilities unsupported on Solaris.Discarding capabilities lists." )
logrus . Warnf ( "Adding or dropping kernel capabilities unsupported on Solaris.Discarding capabilities lists." )
hostConfig . CapAdd = nil
hostConfig . CapDrop = nil
}
if hostConfig . GroupAdd != nil {
warnings = append ( warnings , "Additional groups unsupported on Solaris.Discarding groups lists." )
logrus . Warnf ( "Additional groups unsupported on Solaris.Discarding groups lists." )
hostConfig . GroupAdd = nil
}
if hostConfig . IpcMode != "" {
warnings = append ( warnings , "IPC namespace assignment unsupported on Solaris.Discarding IPC setting." )
logrus . Warnf ( "IPC namespace assignment unsupported on Solaris.Discarding IPC setting." )
hostConfig . IpcMode = ""
}
if hostConfig . PidMode != "" {
warnings = append ( warnings , "PID namespace setting unsupported on Solaris. Running container in host PID namespace." )
logrus . Warnf ( "PID namespace setting unsupported on Solaris. Running container in host PID namespace." )
hostConfig . PidMode = ""
}
if hostConfig . Privileged {
warnings = append ( warnings , "Privileged mode unsupported on Solaris. Discarding privileged mode setting." )
logrus . Warnf ( "Privileged mode unsupported on Solaris. Discarding privileged mode setting." )
hostConfig . Privileged = false
}
if hostConfig . UTSMode != "" {
warnings = append ( warnings , "UTS namespace assignment unsupported on Solaris.Discarding UTS setting." )
logrus . Warnf ( "UTS namespace assignment unsupported on Solaris.Discarding UTS setting." )
hostConfig . UTSMode = ""
}
if hostConfig . CgroupParent != "" {
warnings = append ( warnings , "Specifying Cgroup parent unsupported on Solaris. Discarding cgroup parent setting." )
logrus . Warnf ( "Specifying Cgroup parent unsupported on Solaris. Discarding cgroup parent setting." )
hostConfig . CgroupParent = ""
}
if hostConfig . Ulimits != nil {
warnings = append ( warnings , "Specifying ulimits unsupported on Solaris. Discarding ulimits setting." )
logrus . Warnf ( "Specifying ulimits unsupported on Solaris. Discarding ulimits setting." )
hostConfig . Ulimits = nil
}
2016-03-25 19:38:00 -04:00
return warnings , nil
}
2017-01-07 09:30:25 -05:00
// reloadPlatform updates configuration with platform specific options
// and updates the passed attributes
Implement none, private, and shareable ipc modes
Since the commit d88fe447df0e8 ("Add support for sharing /dev/shm/ and
/dev/mqueue between containers") container's /dev/shm is mounted on the
host first, then bind-mounted inside the container. This is done that
way in order to be able to share this container's IPC namespace
(and the /dev/shm mount point) with another container.
Unfortunately, this functionality breaks container checkpoint/restore
(even if IPC is not shared). Since /dev/shm is an external mount, its
contents is not saved by `criu checkpoint`, and so upon restore any
application that tries to access data under /dev/shm is severily
disappointed (which usually results in a fatal crash).
This commit solves the issue by introducing new IPC modes for containers
(in addition to 'host' and 'container:ID'). The new modes are:
- 'shareable': enables sharing this container's IPC with others
(this used to be the implicit default);
- 'private': disables sharing this container's IPC.
In 'private' mode, container's /dev/shm is truly mounted inside the
container, without any bind-mounting from the host, which solves the
issue.
While at it, let's also implement 'none' mode. The motivation, as
eloquently put by Justin Cormack, is:
> I wondered a while back about having a none shm mode, as currently it is
> not possible to have a totally unwriteable container as there is always
> a /dev/shm writeable mount. It is a bit of a niche case (and clearly
> should never be allowed to be daemon default) but it would be trivial to
> add now so maybe we should...
...so here's yet yet another mode:
- 'none': no /dev/shm mount inside the container (though it still
has its own private IPC namespace).
Now, to ultimately solve the abovementioned checkpoint/restore issue, we'd
need to make 'private' the default mode, but unfortunately it breaks the
backward compatibility. So, let's make the default container IPC mode
per-daemon configurable (with the built-in default set to 'shareable'
for now). The default can be changed either via a daemon CLI option
(--default-shm-mode) or a daemon.json configuration file parameter
of the same name.
Note one can only set either 'shareable' or 'private' IPC modes as a
daemon default (i.e. in this context 'host', 'container', or 'none'
do not make much sense).
Some other changes this patch introduces are:
1. A mount for /dev/shm is added to default OCI Linux spec.
2. IpcMode.Valid() is simplified to remove duplicated code that parsed
'container:ID' form. Note the old version used to check that ID does
not contain a semicolon -- this is no longer the case (tests are
modified accordingly). The motivation is we should either do a
proper check for container ID validity, or don't check it at all
(since it is checked in other places anyway). I chose the latter.
3. IpcMode.Container() is modified to not return container ID if the
mode value does not start with "container:", unifying the check to
be the same as in IpcMode.IsContainer().
3. IPC mode unit tests (runconfig/hostconfig_test.go) are modified
to add checks for newly added values.
[v2: addressed review at https://github.com/moby/moby/pull/34087#pullrequestreview-51345997]
[v3: addressed review at https://github.com/moby/moby/pull/34087#pullrequestreview-53902833]
[v4: addressed the case of upgrading from older daemon, in this case
container.HostConfig.IpcMode is unset and this is valid]
[v5: document old and new IpcMode values in api/swagger.yaml]
[v6: add the 'none' mode, changelog entry to docs/api/version-history.md]
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2017-06-27 17:58:50 -04:00
func ( daemon * Daemon ) reloadPlatform ( conf * config . Config , attributes map [ string ] string ) error {
return nil
2016-05-23 17:49:50 -04:00
}
2016-03-25 19:38:00 -04:00
// verifyDaemonSettings performs validation of daemon config struct
2017-08-09 14:58:31 -04:00
func verifyDaemonSettings ( conf * config . Config ) error {
2016-06-07 03:45:21 -04:00
2017-08-09 14:58:31 -04:00
if conf . DefaultRuntime == "" {
conf . DefaultRuntime = stockRuntimeName
2016-06-07 03:45:21 -04:00
}
2017-08-09 14:58:31 -04:00
if conf . Runtimes == nil {
conf . Runtimes = make ( map [ string ] types . Runtime )
2016-06-07 03:45:21 -04:00
}
stockRuntimeOpts := [ ] string { }
2017-08-09 14:58:31 -04:00
conf . Runtimes [ stockRuntimeName ] = types . Runtime { Path : DefaultRuntimeBinary , Args : stockRuntimeOpts }
2016-06-07 03:45:21 -04:00
2016-03-25 19:38:00 -04:00
return nil
}
2017-08-09 14:58:31 -04:00
// checkSystem validates platform-specific requirements
2016-03-25 19:38:00 -04:00
func checkSystem ( ) error {
// check OS version for compatibility, ensure running in global zone
var err error
var id C . zoneid_t
if id , err = C . getzoneid ( ) ; err != nil {
return fmt . Errorf ( "Exiting. Error getting zone id: %+v" , err )
}
if int ( id ) != 0 {
return fmt . Errorf ( "Exiting because the Docker daemon is not running in the global zone" )
}
v , err := kernel . GetKernelVersion ( )
if kernel . CompareKernelVersion ( * v , kernel . VersionInfo { Kernel : 5 , Major : 12 , Minor : 0 } ) < 0 {
return fmt . Errorf ( "Your Solaris kernel version: %s doesn't support Docker. Please upgrade to 5.12.0" , v . String ( ) )
}
return err
}
// configureMaxThreads sets the Go runtime max threads threshold
// which is 90% of the kernel setting from /proc/sys/kernel/threads-max
2017-08-09 14:58:31 -04:00
func configureMaxThreads ( config * config . Config ) error {
2016-03-25 19:38:00 -04:00
return nil
}
2017-08-09 14:58:31 -04:00
// configureKernelSecuritySupport configures and validates security support for the kernel
2017-05-16 19:56:56 -04:00
func configureKernelSecuritySupport ( config * config . Config , driverNames [ ] string ) error {
2016-03-25 19:38:00 -04:00
return nil
}
2017-08-09 14:58:31 -04:00
func ( daemon * Daemon ) initNetworkController ( config * config . Config , activeSandboxes map [ string ] interface { } ) ( libnetwork . NetworkController , error ) {
2016-06-07 03:45:21 -04:00
netOptions , err := daemon . networkOptions ( config , daemon . PluginStore , activeSandboxes )
if err != nil {
return nil , err
}
controller , err := libnetwork . New ( netOptions ... )
if err != nil {
return nil , fmt . Errorf ( "error obtaining controller instance: %v" , err )
}
// Initialize default network on "null"
if _ , err := controller . NewNetwork ( "null" , "none" , "" , libnetwork . NetworkOptionPersist ( false ) ) ; err != nil {
return nil , fmt . Errorf ( "Error creating default 'null' network: %v" , err )
}
if ! config . DisableBridge {
// Initialize default driver "bridge"
if err := initBridgeDriver ( controller , config ) ; err != nil {
return nil , err
}
}
return controller , nil
}
2017-08-09 14:58:31 -04:00
func initBridgeDriver ( controller libnetwork . NetworkController , config * config . Config ) error {
2016-06-07 03:45:21 -04:00
if n , err := controller . NetworkByName ( "bridge" ) ; err == nil {
if err = n . Delete ( ) ; err != nil {
return fmt . Errorf ( "could not delete the default bridge network: %v" , err )
}
}
bridgeName := bridge . DefaultBridgeName
if config . bridgeConfig . Iface != "" {
bridgeName = config . bridgeConfig . Iface
}
netOption := map [ string ] string {
bridge . BridgeName : bridgeName ,
bridge . DefaultBridge : strconv . FormatBool ( true ) ,
netlabel . DriverMTU : strconv . Itoa ( config . Mtu ) ,
bridge . EnableICC : strconv . FormatBool ( config . bridgeConfig . InterContainerCommunication ) ,
}
// --ip processing
if config . bridgeConfig . DefaultIP != nil {
netOption [ bridge . DefaultBindingIP ] = config . bridgeConfig . DefaultIP . String ( )
}
var ipamV4Conf * libnetwork . IpamConf
ipamV4Conf = & libnetwork . IpamConf { AuxAddresses : make ( map [ string ] string ) }
nwList , _ , err := netutils . ElectInterfaceAddresses ( bridgeName )
if err != nil {
return errors . Wrap ( err , "list bridge addresses failed" )
}
nw := nwList [ 0 ]
if len ( nwList ) > 1 && config . bridgeConfig . FixedCIDR != "" {
_ , fCIDR , err := net . ParseCIDR ( config . bridgeConfig . FixedCIDR )
if err != nil {
return errors . Wrap ( err , "parse CIDR failed" )
}
// Iterate through in case there are multiple addresses for the bridge
for _ , entry := range nwList {
if fCIDR . Contains ( entry . IP ) {
nw = entry
break
}
}
}
ipamV4Conf . PreferredPool = lntypes . GetIPNetCanonical ( nw ) . String ( )
hip , _ := lntypes . GetHostPartIP ( nw . IP , nw . Mask )
if hip . IsGlobalUnicast ( ) {
ipamV4Conf . Gateway = nw . IP . String ( )
}
if config . bridgeConfig . IP != "" {
ipamV4Conf . PreferredPool = config . bridgeConfig . IP
ip , _ , err := net . ParseCIDR ( config . bridgeConfig . IP )
if err != nil {
return err
}
ipamV4Conf . Gateway = ip . String ( )
} else if bridgeName == bridge . DefaultBridgeName && ipamV4Conf . PreferredPool != "" {
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 )
}
if config . bridgeConfig . FixedCIDR != "" {
_ , fCIDR , err := net . ParseCIDR ( config . bridgeConfig . FixedCIDR )
if err != nil {
return err
}
ipamV4Conf . SubPool = fCIDR . String ( )
}
if config . bridgeConfig . DefaultGatewayIPv4 != nil {
ipamV4Conf . AuxAddresses [ "DefaultGatewayIPv4" ] = config . bridgeConfig . DefaultGatewayIPv4 . String ( )
}
v4Conf := [ ] * libnetwork . IpamConf { ipamV4Conf }
v6Conf := [ ] * libnetwork . IpamConf { }
// Initialize default network on "bridge" with the same name
_ , err = controller . NewNetwork ( "bridge" , "bridge" , "" ,
libnetwork . NetworkOptionDriverOpts ( netOption ) ,
libnetwork . NetworkOptionIpam ( "default" , "" , v4Conf , v6Conf , nil ) ,
libnetwork . NetworkOptionDeferIPv6Alloc ( false ) )
if err != nil {
return fmt . Errorf ( "Error creating default 'bridge' network: %v" , err )
}
return nil
2016-03-25 19:38:00 -04:00
}
// registerLinks sets up links between containers and writes the
// configuration out for persistence.
func ( daemon * Daemon ) registerLinks ( container * container . Container , hostConfig * containertypes . HostConfig ) error {
return nil
}
func ( daemon * Daemon ) cleanupMounts ( ) error {
return nil
}
// conditionalMountOnStart is a platform specific helper function during the
// container start to call mount.
func ( daemon * Daemon ) conditionalMountOnStart ( container * container . Container ) error {
2016-06-07 03:45:21 -04:00
return daemon . Mount ( container )
2016-03-25 19:38:00 -04:00
}
// conditionalUnmountOnCleanup is a platform specific helper function called
// during the cleanup of a container to unmount.
func ( daemon * Daemon ) conditionalUnmountOnCleanup ( container * container . Container ) error {
return daemon . Unmount ( container )
}
2017-08-09 14:58:31 -04:00
func driverOptions ( config * config . Config ) [ ] nwconfig . Option {
2016-03-25 19:38:00 -04:00
return [ ] nwconfig . Option { }
}
func ( daemon * Daemon ) stats ( c * container . Container ) ( * types . StatsJSON , error ) {
return nil , nil
}
// setDefaultIsolation determine the default isolation mode for the
// daemon to run in. This is only applicable on Windows
func ( daemon * Daemon ) setDefaultIsolation ( ) error {
return nil
}
func rootFSToAPIType ( rootfs * image . RootFS ) types . RootFS {
return types . RootFS { }
}
2016-07-11 18:26:23 -04:00
2017-08-09 14:58:31 -04:00
func setupDaemonProcess ( config * config . Config ) error {
2016-07-11 18:26:23 -04:00
return nil
}
2016-09-06 09:49:10 -04:00
2016-09-02 09:20:54 -04:00
func ( daemon * Daemon ) setupSeccompProfile ( ) error {
return nil
}
2017-05-31 20:11:42 -04:00
func getRealPath ( path string ) ( string , error ) {
return fileutils . ReadSymlinkedDirectory ( path )
}