Merge pull request #35285 from crosbymichael/solaris

Remove solaris files
This commit is contained in:
Sebastiaan van Stijn 2017-10-25 15:14:04 +02:00 committed by GitHub
commit 17bb1d3663
41 changed files with 14 additions and 1776 deletions

View file

@ -1,19 +0,0 @@
# Defines an image that hosts a native Docker build environment for Solaris
# TODO: Improve stub
FROM solaris:latest
# compile and runtime deps
RUN pkg install --accept \
git \
gnu-coreutils \
gnu-make \
gnu-tar \
diagnostic/top \
golang \
library/golang/* \
developer/gcc-*
ENV GOPATH /go/:/usr/lib/gocode/1.5/
WORKDIR /go/src/github.com/docker/docker
COPY . /go/src/github.com/docker/docker

View file

@ -3,7 +3,6 @@
package main
import (
"runtime"
"testing"
"github.com/docker/docker/daemon/config"
@ -12,9 +11,6 @@ import (
)
func TestDaemonParseShmSize(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("ShmSize not supported on Solaris\n")
}
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
conf := &config.Config{}

View file

@ -1,64 +0,0 @@
// +build solaris
package main
import (
"fmt"
"net"
"path/filepath"
"github.com/docker/docker/libcontainerd"
"golang.org/x/sys/unix"
)
const defaultDaemonConfigFile = ""
// setDefaultUmask sets the umask to 0022 to avoid problems
// caused by custom umask
func setDefaultUmask() error {
desiredUmask := 0022
unix.Umask(desiredUmask)
if umask := unix.Umask(desiredUmask); umask != desiredUmask {
return fmt.Errorf("failed to set umask: expected %#o, got %#o", desiredUmask, umask)
}
return nil
}
func getDaemonConfDir(_ string) string {
return "/etc/docker"
}
// setupConfigReloadTrap configures the USR2 signal to reload the configuration.
func (cli *DaemonCli) setupConfigReloadTrap() {
}
// preNotifySystem sends a message to the host when the API is active, but before the daemon is
func preNotifySystem() {
}
// notifySystem sends a message to the host when the server is ready to be used
func notifySystem() {
}
func (cli *DaemonCli) getPlatformRemoteOptions() ([]libcontainerd.RemoteOption, error) {
return nil, nil
}
// getSwarmRunRoot gets the root directory for swarm to store runtime state
// For example, the control socket
func (cli *DaemonCli) getSwarmRunRoot() string {
return filepath.Join(cli.Config.ExecRoot, "swarm")
}
func allocateDaemonPort(addr string) error {
return nil
}
// notifyShutdown is called after the daemon shuts down but before the process exits.
func notifyShutdown(err error) {
}
func wrapListeners(proto string, ls []net.Listener) []net.Listener {
return ls
}

View file

@ -1,4 +0,0 @@
FROM solaris
EXPOSE 80/tcp
COPY httpserver .
CMD ["./httpserver"]

View file

@ -1,5 +0,0 @@
// +build solaris
package daemon
const bindMountType = "lofs"

View file

@ -129,8 +129,8 @@ func (daemon *Daemon) Commit(name string, c *backend.ContainerCommitConfig) (str
return "", err
}
// It is not possible to commit a running container on Windows and on Solaris.
if (runtime.GOOS == "windows" || runtime.GOOS == "solaris") && container.IsRunning() {
// It is not possible to commit a running container on Windows
if (runtime.GOOS == "windows") && container.IsRunning() {
return "", errors.Errorf("%+v does not support commit of a running container", runtime.GOOS)
}

View file

@ -204,9 +204,6 @@ func New() *Config {
// ParseClusterAdvertiseSettings parses the specified advertise settings
func ParseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) {
if runtime.GOOS == "solaris" && (clusterAdvertise != "" || clusterStore != "") {
return "", errors.New("Cluster Advertise Settings not supported on Solaris")
}
if clusterAdvertise == "" {
return "", daemondiscovery.ErrDiscoveryDisabled
}

View file

@ -3,7 +3,6 @@ package config
import (
"io/ioutil"
"os"
"runtime"
"strings"
"testing"
@ -38,9 +37,6 @@ func TestDaemonBrokenConfiguration(t *testing.T) {
}
func TestParseClusterAdvertiseSettings(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("ClusterSettings not supported on Solaris\n")
}
_, err := ParseClusterAdvertiseSettings("something", "")
if err != discovery.ErrDiscoveryDisabled {
t.Fatalf("expected discovery disabled error, got %v\n", err)

View file

@ -1,47 +0,0 @@
// +build solaris
package daemon
import (
"github.com/docker/docker/container"
"github.com/docker/docker/runconfig"
"github.com/docker/libnetwork"
)
func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
return nil, nil
}
func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
return nil
}
func killProcessDirectly(container *container.Container) error {
return nil
}
func detachMounted(path string) error {
return nil
}
func isLinkable(child *container.Container) bool {
// A container is linkable only if it belongs to the default network
_, ok := child.NetworkSettings.Networks[runconfig.DefaultDaemonNetworkMode().NetworkName()]
return ok
}
func enableIPOnPredefinedNetwork() bool {
return false
}
func (daemon *Daemon) isNetworkHotPluggable() bool {
return false
}
func setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
return nil
}
func (daemon *Daemon) initializeNetworkingPaths(container *container.Container, nc *container.Container) error {
return nil
}

View file

@ -96,10 +96,6 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) (
return nil, err
}
os = img.OS
if runtime.GOOS == "solaris" && img.OS != "solaris " {
return nil, errors.New("operating system on which parent image was created is not Solaris")
}
imgID = img.ID()
if runtime.GOOS == "windows" && img.OS == "linux" && !system.LCOWSupported() {

View file

@ -1,530 +0,0 @@
// +build solaris,cgo
package daemon
import (
"fmt"
"net"
"strconv"
"github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/containerfs"
"github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/sysinfo"
"github.com/docker/libnetwork"
nwconfig "github.com/docker/libnetwork/config"
"github.com/docker/libnetwork/drivers/solaris/bridge"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
lntypes "github.com/docker/libnetwork/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
//#include <zone.h>
import "C"
const (
platformSupported = true
solarisMinCPUShares = 1
solarisMaxCPUShares = 65535
)
func getMemoryResources(config containertypes.Resources) specs.CappedMemory {
memory := specs.CappedMemory{
DisableOOMKiller: config.OomKillDisable,
}
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
}
func (daemon *Daemon) cleanupMountsByID(id string) error {
return nil
}
func (daemon *Daemon) parseSecurityOpt(container *container.Container, hostConfig *containertypes.HostConfig) error {
return parseSecurityOpt(container, hostConfig)
}
func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
//Since hostConfig.SecurityOpt is specifically defined as a "List of string values to
//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
}
func setupRemappedRoot(config *config.Config) (*idtools.IDMappings, error) {
return nil, nil
}
func setupDaemonRoot(config *config.Config, rootDir string, rootIDs idtools.IDPair) error {
return nil
}
func (daemon *Daemon) getLayerInit() func(containerfs.ContainerFS) error {
return nil
}
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 {
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
}
return nil
}
// UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
func UsingSystemd(config *config.Config) bool {
return false
}
// 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) {
fixMemorySwappiness(resources)
warnings := []string{}
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.
if hostConfig.MemorySwappiness != nil && !sysInfo.MemorySwappiness {
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
}
return warnings, nil
}
// reloadPlatform updates configuration with platform specific options
// and updates the passed attributes
func (daemon *Daemon) reloadPlatform(conf *config.Config, attributes map[string]string) error {
return nil
}
// verifyDaemonSettings performs validation of daemon config struct
func verifyDaemonSettings(conf *config.Config) error {
if conf.DefaultRuntime == "" {
conf.DefaultRuntime = stockRuntimeName
}
if conf.Runtimes == nil {
conf.Runtimes = make(map[string]types.Runtime)
}
stockRuntimeOpts := []string{}
conf.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary, Args: stockRuntimeOpts}
return nil
}
// checkSystem validates platform-specific requirements
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
func configureMaxThreads(config *config.Config) error {
return nil
}
// configureKernelSecuritySupport configures and validates security support for the kernel
func configureKernelSecuritySupport(config *config.Config, driverNames []string) error {
return nil
}
func (daemon *Daemon) initNetworkController(config *config.Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
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
}
func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error {
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
}
// 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 {
return daemon.Mount(container)
}
// 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)
}
func driverOptions(config *config.Config) []nwconfig.Option {
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{}
}
func setupDaemonProcess(config *config.Config) error {
return nil
}
func (daemon *Daemon) setupSeccompProfile() error {
return nil
}
func getRealPath(path string) (string, error) {
return fileutils.ReadSymlinkedDirectory(path)
}

View file

@ -1,96 +0,0 @@
// +build solaris,cgo
package graphdriver
/*
#include <sys/statvfs.h>
#include <stdlib.h>
static inline struct statvfs *getstatfs(char *s) {
struct statvfs *buf;
int err;
buf = (struct statvfs *)malloc(sizeof(struct statvfs));
err = statvfs(s, buf);
return buf;
}
*/
import "C"
import (
"path/filepath"
"unsafe"
"github.com/docker/docker/pkg/mount"
"github.com/sirupsen/logrus"
)
const (
// FsMagicZfs filesystem id for Zfs
FsMagicZfs = FsMagic(0x2fc12fc1)
)
var (
// Slice of drivers that should be used in an order
priority = []string{
"zfs",
}
// FsNames maps filesystem id to name of the filesystem.
FsNames = map[FsMagic]string{
FsMagicZfs: "zfs",
}
)
// GetFSMagic returns the filesystem id given the path.
func GetFSMagic(rootpath string) (FsMagic, error) {
return 0, nil
}
type fsChecker struct {
t FsMagic
}
func (c *fsChecker) IsMounted(path string) bool {
m, _ := Mounted(c.t, path)
return m
}
// NewFsChecker returns a checker configured for the provided FsMagic
func NewFsChecker(t FsMagic) Checker {
return &fsChecker{
t: t,
}
}
// NewDefaultChecker returns a check that parses /proc/mountinfo to check
// if the specified path is mounted.
// No-op on Solaris.
func NewDefaultChecker() Checker {
return &defaultChecker{}
}
type defaultChecker struct {
}
func (c *defaultChecker) IsMounted(path string) bool {
m, _ := mount.Mounted(path)
return m
}
// Mounted checks if the given path is mounted as the fs type
//Solaris supports only ZFS for now
func Mounted(fsType FsMagic, mountPath string) (bool, error) {
cs := C.CString(filepath.Dir(mountPath))
defer C.free(unsafe.Pointer(cs))
buf := C.getstatfs(cs)
defer C.free(unsafe.Pointer(buf))
// on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
(buf.f_basetype[3] != 0) {
logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", mountPath)
return false, ErrPrerequisites
}
return true, nil
}

View file

@ -1,58 +0,0 @@
// +build solaris,cgo
package zfs
/*
#include <sys/statvfs.h>
#include <stdlib.h>
static inline struct statvfs *getstatfs(char *s) {
struct statvfs *buf;
int err;
buf = (struct statvfs *)malloc(sizeof(struct statvfs));
err = statvfs(s, buf);
return buf;
}
*/
import "C"
import (
"path/filepath"
"strings"
"unsafe"
"github.com/docker/docker/daemon/graphdriver"
"github.com/sirupsen/logrus"
)
func checkRootdirFs(rootdir string) error {
cs := C.CString(filepath.Dir(rootdir))
defer C.free(unsafe.Pointer(cs))
buf := C.getstatfs(cs)
defer C.free(unsafe.Pointer(buf))
// on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
(buf.f_basetype[3] != 0) {
logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
return graphdriver.ErrPrerequisites
}
return nil
}
/* rootfs is introduced to comply with the OCI spec
which states that root filesystem must be mounted at <CID>/rootfs/ instead of <CID>/
*/
func getMountpoint(id string) string {
maxlen := 12
// we need to preserve filesystem suffix
suffix := strings.SplitN(id, "-", 2)
if len(suffix) > 1 {
return filepath.Join(id[:maxlen]+"-"+suffix[1], "rootfs", "root")
}
return filepath.Join(id[:maxlen], "rootfs", "root")
}

View file

@ -1,15 +0,0 @@
// +build solaris,cgo
package initlayer
import "github.com/docker/docker/pkg/containerfs"
// Setup populates a directory with mountpoints suitable
// for bind-mounting dockerinit into the container. The mountpoint is simply an
// empty file at /.dockerinit
//
// This extra layer is used by all containers as the top-most ro layer. It protects
// the container from unwanted side-effects on the rw layer.
func Setup(initLayer containerfs.ContainerFS, rootUID, rootGID int) error {
return nil
}

View file

@ -3,7 +3,6 @@ package daemon
import (
"fmt"
"net"
"runtime"
"sort"
"strings"
"sync"
@ -452,9 +451,6 @@ func (daemon *Daemon) UpdateContainerServiceConfig(containerName string, service
// network. If either cannot be found, an err is returned. If the
// network cannot be set up, an err is returned.
func (daemon *Daemon) ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error {
if runtime.GOOS == "solaris" {
return errors.New("docker network connect is unsupported on Solaris platform")
}
container, err := daemon.GetContainer(containerName)
if err != nil {
return err
@ -465,9 +461,6 @@ func (daemon *Daemon) ConnectContainerToNetwork(containerName, networkName strin
// DisconnectContainerFromNetwork disconnects the given container from
// the given network. If either cannot be found, an err is returned.
func (daemon *Daemon) DisconnectContainerFromNetwork(containerName string, networkName string, force bool) error {
if runtime.GOOS == "solaris" {
return errors.New("docker network disconnect is unsupported on Solaris platform")
}
container, err := daemon.GetContainer(containerName)
if err != nil {
if force {

View file

@ -1,186 +0,0 @@
package daemon
import (
"fmt"
"sort"
"strconv"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/oci"
"github.com/docker/libnetwork"
"github.com/opencontainers/runtime-spec/specs-go"
)
func setResources(s *specs.Spec, r containertypes.Resources) error {
mem := getMemoryResources(r)
s.Solaris.CappedMemory = &mem
capCPU := getCPUResources(r)
s.Solaris.CappedCPU = &capCPU
return nil
}
func setUser(s *specs.Spec, c *container.Container) error {
uid, gid, additionalGids, err := getUser(c, c.Config.User)
if err != nil {
return err
}
s.Process.User.UID = uid
s.Process.User.GID = gid
s.Process.User.AdditionalGids = additionalGids
return nil
}
func getUser(c *container.Container, username string) (uint32, uint32, []uint32, error) {
return 0, 0, nil, nil
}
func (daemon *Daemon) getRunzAnet(ep libnetwork.Endpoint) (specs.Anet, error) {
var (
linkName string
lowerLink string
defRouter string
)
epInfo := ep.Info()
if epInfo == nil {
return specs.Anet{}, fmt.Errorf("invalid endpoint")
}
nw, err := daemon.GetNetworkByName(ep.Network())
if err != nil {
return specs.Anet{}, fmt.Errorf("Failed to get network %s: %v", ep.Network(), err)
}
// Evaluate default router, linkname and lowerlink for interface endpoint
switch nw.Type() {
case "bridge":
defRouter = epInfo.Gateway().String()
linkName = "net0" // Should always be net0 for a container
// TODO We construct lowerlink here exactly as done for solaris bridge
// initialization. Need modular code to reuse.
options := nw.Info().DriverOptions()
nwName := options["com.docker.network.bridge.name"]
lastChar := nwName[len(nwName)-1:]
if _, err = strconv.Atoi(lastChar); err != nil {
lowerLink = nwName + "_0"
} else {
lowerLink = nwName
}
case "overlay":
defRouter = ""
linkName = "net1"
// TODO Follows generateVxlanName() in solaris overlay.
id := nw.ID()
if len(nw.ID()) > 12 {
id = nw.ID()[:12]
}
lowerLink = "vx_" + id + "_0"
}
runzanet := specs.Anet{
Linkname: linkName,
Lowerlink: lowerLink,
Allowedaddr: epInfo.Iface().Address().String(),
Configallowedaddr: "true",
Defrouter: defRouter,
Linkprotection: "mac-nospoof, ip-nospoof",
Macaddress: epInfo.Iface().MacAddress().String(),
}
return runzanet, nil
}
func (daemon *Daemon) setNetworkInterface(s *specs.Spec, c *container.Container) error {
var anets []specs.Anet
sb, err := daemon.netController.SandboxByID(c.NetworkSettings.SandboxID)
if err != nil {
return fmt.Errorf("Could not obtain sandbox for container")
}
// Populate interfaces required for each endpoint
for _, ep := range sb.Endpoints() {
runzanet, err := daemon.getRunzAnet(ep)
if err != nil {
return fmt.Errorf("Failed to get interface information for endpoint %d: %v", ep.ID(), err)
}
anets = append(anets, runzanet)
}
s.Solaris.Anet = anets
if anets != nil {
s.Solaris.Milestone = "svc:/milestone/container:default"
}
return nil
}
func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container) error {
linkedEnv, err := daemon.setupLinkedContainers(c)
if err != nil {
return err
}
s.Root = specs.Root{
Path: c.BaseFS.Dir(c.BaseFS.Path()),
Readonly: c.HostConfig.ReadonlyRootfs,
}
if err := c.SetupWorkingDirectory(daemon.idMappings.RootPair()); err != nil {
return err
}
cwd := c.Config.WorkingDir
s.Process.Args = append([]string{c.Path}, c.Args...)
s.Process.Cwd = cwd
s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv)
s.Process.Terminal = c.Config.Tty
s.Hostname = c.FullHostname()
return nil
}
func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
s := oci.DefaultSpec()
if err := daemon.populateCommonSpec(&s, c); err != nil {
return nil, err
}
if err := setResources(&s, c.HostConfig.Resources); err != nil {
return nil, fmt.Errorf("runtime spec resources: %v", err)
}
if err := setUser(&s, c); err != nil {
return nil, fmt.Errorf("spec user: %v", err)
}
if err := daemon.setNetworkInterface(&s, c); err != nil {
return nil, err
}
if err := daemon.setupIpcDirs(c); err != nil {
return nil, err
}
ms, err := daemon.setupMounts(c)
if err != nil {
return nil, err
}
ms = append(ms, c.IpcMounts()...)
tmpfsMounts, err := c.TmpfsMounts()
if err != nil {
return nil, err
}
ms = append(ms, tmpfsMounts...)
sort.Sort(mounts(ms))
return (*specs.Spec)(&s), nil
}
// mergeUlimits merge the Ulimits from HostConfig with daemon defaults, and update HostConfig
// It will do nothing on non-Linux platform
func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) {
return
}

View file

@ -3,7 +3,6 @@ package daemon
import (
"encoding/json"
"errors"
"fmt"
"runtime"
"time"
@ -20,9 +19,6 @@ import (
// ContainerStats writes information about the container to the stream
// given in the config object.
func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *backend.ContainerStatsConfig) error {
if runtime.GOOS == "solaris" {
return fmt.Errorf("%+v does not support stats", runtime.GOOS)
}
// Engine API version (used for backwards compatibility)
apiVersion := config.Version

View file

@ -1,29 +0,0 @@
package stats
import (
"github.com/docker/docker/container"
)
// platformNewStatsCollector performs platform specific initialisation of the
// Collector structure. This is a no-op on Windows.
func platformNewStatsCollector(s *Collector) {
}
// Collect registers the container with the collector and adds it to
// the event loop for collection on the specified interval returning
// a channel for the subscriber to receive on.
// Currently not supported on Solaris
func (s *Collector) Collect(c *container.Container) chan interface{} {
return nil
}
// StopCollection closes the channels for all subscribers and removes
// the container from metrics collection.
// Currently not supported on Solaris
func (s *Collector) StopCollection(c *container.Container) {
}
// Unsubscribe removes a specific subscriber from receiving updates for a container's stats.
// Currently not supported on Solaris
func (s *Collector) Unsubscribe(c *container.Container, ch chan interface{}) {
}

View file

@ -95,13 +95,6 @@ if [ "$AUTO_GOPATH" ]; then
mkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"
ln -sf ../../../.. .gopath/src/"${DOCKER_PKG}"
export GOPATH="${PWD}/.gopath"
if [ "$(go env GOOS)" = 'solaris' ]; then
# sys/unix is installed outside the standard library on solaris
# TODO need to allow for version change, need to get version from go
export GO_VERSION=${GO_VERSION:-"1.8.1"}
export GOPATH="${GOPATH}:/usr/lib/gocode/${GO_VERSION}"
fi
fi
if [ ! "$GOPATH" ]; then

View file

@ -207,10 +207,6 @@ release_build() {
linux)
s3Os=Linux
;;
solaris)
echo skipping solaris release
return 0
;;
windows)
# this is windows use the .zip and .exe extensions for the files.
s3Os=Windows

View file

@ -17,9 +17,6 @@ BUILDFLAGS=( -tags "netgo seccomp libdm_no_deferred_remove" )
TESTDIRS="${TESTDIRS:-"./..."}"
exclude_paths="/vendor/|/integration"
if [ "$(go env GOHOSTOS)" = 'solaris' ]; then
exclude_paths="$exclude_paths|/daemon/graphdriver"
fi
pkg_list=$(go list $TESTDIRS | grep -vE "($exclude_paths)")
go test -cover "${BUILDFLAGS[@]}" $TESTFLAGS $pkg_list

View file

@ -39,11 +39,8 @@ func DefaultSpec() specs.Spec {
func DefaultOSSpec(osName string) specs.Spec {
if osName == "windows" {
return DefaultWindowsSpec()
} else if osName == "solaris" {
return DefaultSolarisSpec()
} else {
return DefaultLinuxSpec()
}
return DefaultLinuxSpec()
}
// DefaultWindowsSpec create a default spec for running Windows containers
@ -56,15 +53,6 @@ func DefaultWindowsSpec() specs.Spec {
}
}
// DefaultSolarisSpec create a default spec for running Solaris containers
func DefaultSolarisSpec() specs.Spec {
s := specs.Spec{
Version: "0.6.0",
}
s.Solaris = &specs.Solaris{}
return s
}
// DefaultLinuxSpec create a default spec for running Linux containers
func DefaultLinuxSpec() specs.Spec {
s := specs.Spec{

View file

@ -72,12 +72,7 @@ func TestIsArchivePathInvalidFile(t *testing.T) {
}
func TestIsArchivePathTar(t *testing.T) {
var whichTar string
if runtime.GOOS == "solaris" {
whichTar = "gtar"
} else {
whichTar = "tar"
}
whichTar := "tar"
cmdStr := fmt.Sprintf("touch /tmp/archivedata && %s -cf /tmp/archive /tmp/archivedata && gzip --stdout /tmp/archive > /tmp/archive.gz", whichTar)
cmd := exec.Command("sh", "-c", cmdStr)
output, err := cmd.CombinedOutput()

View file

@ -8,7 +8,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"syscall"
"testing"
@ -224,9 +223,6 @@ func TestTarWithBlockCharFifo(t *testing.T) {
// TestTarUntarWithXattr is Unix as Lsetxattr is not supported on Windows
func TestTarUntarWithXattr(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip()
}
origin, err := ioutil.TempDir("", "docker-test-untar-origin")
require.NoError(t, err)
defer os.RemoveAll(origin)

View file

@ -7,16 +7,11 @@ import (
"io/ioutil"
"os"
"path"
"runtime"
"sort"
"testing"
)
func TestHardLinkOrder(t *testing.T) {
//TODO Should run for Solaris
if runtime.GOOS == "solaris" {
t.Skip("gcp failures on Solaris")
}
names := []string{"file1.txt", "file2.txt", "file3.txt"}
msg := []byte("Hey y'all")

View file

@ -22,15 +22,7 @@ func max(x, y int) int {
}
func copyDir(src, dst string) error {
cmd := exec.Command("cp", "-a", src, dst)
if runtime.GOOS == "solaris" {
cmd = exec.Command("gcp", "-a", src, dst)
}
if err := cmd.Run(); err != nil {
return err
}
return nil
return exec.Command("cp", "-a", src, dst).Run()
}
type FileType uint32
@ -247,9 +239,8 @@ func TestChangesWithChangesGH13590(t *testing.T) {
func TestChangesDirsEmpty(t *testing.T) {
// TODO Windows. There may be a way of running this, but turning off for now
// as createSampleDir uses symlinks.
// TODO Should work for Solaris
if runtime.GOOS == "windows" || runtime.GOOS == "solaris" {
t.Skip("symlinks on Windows; gcp failure on Solaris")
if runtime.GOOS == "windows" {
t.Skip("symlinks on Windows")
}
src, err := ioutil.TempDir("", "docker-changes-test")
require.NoError(t, err)
@ -335,9 +326,8 @@ func mutateSampleDir(t *testing.T, root string) {
func TestChangesDirsMutated(t *testing.T) {
// TODO Windows. There may be a way of running this, but turning off for now
// as createSampleDir uses symlinks.
// TODO Should work for Solaris
if runtime.GOOS == "windows" || runtime.GOOS == "solaris" {
t.Skip("symlinks on Windows; gcp failures on Solaris")
if runtime.GOOS == "windows" {
t.Skip("symlinks on Windows")
}
src, err := ioutil.TempDir("", "docker-changes-test")
require.NoError(t, err)
@ -392,9 +382,8 @@ func TestChangesDirsMutated(t *testing.T) {
func TestApplyLayer(t *testing.T) {
// TODO Windows. There may be a way of running this, but turning off for now
// as createSampleDir uses symlinks.
// TODO Should work for Solaris
if runtime.GOOS == "windows" || runtime.GOOS == "solaris" {
t.Skip("symlinks on Windows; gcp failures on Solaris")
if runtime.GOOS == "windows" {
t.Skip("symlinks on Windows")
}
src, err := ioutil.TempDir("", "docker-changes-test")
require.NoError(t, err)

View file

@ -197,8 +197,8 @@ func TestChrootTarUntarWithSymlink(t *testing.T) {
func TestChrootCopyWithTar(t *testing.T) {
// TODO Windows: Figure out why this is failing
if runtime.GOOS == "windows" || runtime.GOOS == "solaris" {
t.Skip("Failing on Windows and Solaris")
if runtime.GOOS == "windows" {
t.Skip("Failing on Windows")
}
tmpdir, err := ioutil.TempDir("", "docker-TestChrootCopyWithTar")
if err != nil {

View file

@ -1,7 +0,0 @@
package fileutils
// GetTotalUsedFds Returns the number of used File Descriptors.
// On Solaris these limits are per process and not systemwide
func GetTotalUsedFds() int {
return -1
}

View file

@ -1,34 +0,0 @@
// +build solaris,cgo
package mount
import (
"unsafe"
"golang.org/x/sys/unix"
)
// #include <stdlib.h>
// #include <stdio.h>
// #include <sys/mount.h>
// int Mount(const char *spec, const char *dir, int mflag,
// char *fstype, char *dataptr, int datalen, char *optptr, int optlen) {
// return mount(spec, dir, mflag, fstype, dataptr, datalen, optptr, optlen);
// }
import "C"
func mount(device, target, mType string, flag uintptr, data string) error {
spec := C.CString(device)
dir := C.CString(target)
fstype := C.CString(mType)
_, err := C.Mount(spec, dir, C.int(flag), fstype, nil, 0, nil, 0)
C.free(unsafe.Pointer(spec))
C.free(unsafe.Pointer(dir))
C.free(unsafe.Pointer(fstype))
return err
}
func unmount(target string, flag int) error {
err := unix.Unmount(target, flag)
return err
}

View file

@ -1,44 +0,0 @@
// +build solaris,cgo
package mount
/*
#include <stdio.h>
#include <stdlib.h>
#include <sys/mnttab.h>
*/
import "C"
import (
"fmt"
"unsafe"
)
func parseMountTable() ([]*Info, error) {
path := C.CString(C.MNTTAB)
defer C.free(unsafe.Pointer(path))
mode := C.CString("r")
defer C.free(unsafe.Pointer(mode))
mnttab := C.fopen(path, mode)
if mnttab == nil {
return nil, fmt.Errorf("Failed to open %s", C.MNTTAB)
}
var out []*Info
var mp C.struct_mnttab
ret := C.getmntent(mnttab, &mp)
for ret == 0 {
var mountinfo Info
mountinfo.Mountpoint = C.GoString(mp.mnt_mountp)
mountinfo.Source = C.GoString(mp.mnt_special)
mountinfo.Fstype = C.GoString(mp.mnt_fstype)
mountinfo.Opts = C.GoString(mp.mnt_mntopts)
out = append(out, &mountinfo)
ret = C.getmntent(mnttab, &mp)
}
C.fclose(mnttab)
return out, nil
}

View file

@ -1,58 +0,0 @@
// +build solaris
package mount
// MakeShared ensures a mounted filesystem has the SHARED mount option enabled.
// See the supported options in flags.go for further reference.
func MakeShared(mountPoint string) error {
return ensureMountedAs(mountPoint, "shared")
}
// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled.
// See the supported options in flags.go for further reference.
func MakeRShared(mountPoint string) error {
return ensureMountedAs(mountPoint, "rshared")
}
// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled.
// See the supported options in flags.go for further reference.
func MakePrivate(mountPoint string) error {
return ensureMountedAs(mountPoint, "private")
}
// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option
// enabled. See the supported options in flags.go for further reference.
func MakeRPrivate(mountPoint string) error {
return ensureMountedAs(mountPoint, "rprivate")
}
// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled.
// See the supported options in flags.go for further reference.
func MakeSlave(mountPoint string) error {
return ensureMountedAs(mountPoint, "slave")
}
// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled.
// See the supported options in flags.go for further reference.
func MakeRSlave(mountPoint string) error {
return ensureMountedAs(mountPoint, "rslave")
}
// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option
// enabled. See the supported options in flags.go for further reference.
func MakeUnbindable(mountPoint string) error {
return ensureMountedAs(mountPoint, "unbindable")
}
// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount
// option enabled. See the supported options in flags.go for further reference.
func MakeRUnbindable(mountPoint string) error {
return ensureMountedAs(mountPoint, "runbindable")
}
func ensureMountedAs(mountPoint, options string) error {
// TODO: Solaris does not support bind mounts.
// Evaluate lofs and also look at the relevant
// mount flags to be supported.
return nil
}

View file

@ -1,37 +0,0 @@
// +build solaris,cgo
package operatingsystem
/*
#include <zone.h>
*/
import "C"
import (
"bytes"
"errors"
"io/ioutil"
)
var etcOsRelease = "/etc/release"
// GetOperatingSystem gets the name of the current operating system.
func GetOperatingSystem() (string, error) {
b, err := ioutil.ReadFile(etcOsRelease)
if err != nil {
return "", err
}
if i := bytes.Index(b, []byte("\n")); i >= 0 {
b = bytes.Trim(b[:i], " ")
return string(b), nil
}
return "", errors.New("release not found")
}
// IsContainerized returns true if we are running inside a container.
func IsContainerized() (bool, error) {
if C.getzoneid() != 0 {
return true, nil
}
return false, nil
}

View file

@ -1,42 +0,0 @@
package signal
import (
"syscall"
)
// SignalMap is a map of Solaris signals.
// SIGINFO and SIGTHR not defined for Solaris
var SignalMap = map[string]syscall.Signal{
"ABRT": syscall.SIGABRT,
"ALRM": syscall.SIGALRM,
"BUF": syscall.SIGBUS,
"CHLD": syscall.SIGCHLD,
"CONT": syscall.SIGCONT,
"EMT": syscall.SIGEMT,
"FPE": syscall.SIGFPE,
"HUP": syscall.SIGHUP,
"ILL": syscall.SIGILL,
"INT": syscall.SIGINT,
"IO": syscall.SIGIO,
"IOT": syscall.SIGIOT,
"KILL": syscall.SIGKILL,
"LWP": syscall.SIGLWP,
"PIPE": syscall.SIGPIPE,
"PROF": syscall.SIGPROF,
"QUIT": syscall.SIGQUIT,
"SEGV": syscall.SIGSEGV,
"STOP": syscall.SIGSTOP,
"SYS": syscall.SIGSYS,
"TERM": syscall.SIGTERM,
"TRAP": syscall.SIGTRAP,
"TSTP": syscall.SIGTSTP,
"TTIN": syscall.SIGTTIN,
"TTOU": syscall.SIGTTOU,
"URG": syscall.SIGURG,
"USR1": syscall.SIGUSR1,
"USR2": syscall.SIGUSR2,
"VTALRM": syscall.SIGVTALRM,
"WINCH": syscall.SIGWINCH,
"XCPU": syscall.SIGXCPU,
"XFSZ": syscall.SIGXFSZ,
}

View file

@ -1,121 +0,0 @@
// +build solaris,cgo
package sysinfo
import (
"bytes"
"os/exec"
"strconv"
"strings"
)
/*
#cgo LDFLAGS: -llgrp
#include <unistd.h>
#include <stdlib.h>
#include <sys/lgrp_user.h>
int getLgrpCount() {
lgrp_cookie_t lgrpcookie = LGRP_COOKIE_NONE;
uint_t nlgrps;
if ((lgrpcookie = lgrp_init(LGRP_VIEW_OS)) == LGRP_COOKIE_NONE) {
return -1;
}
nlgrps = lgrp_nlgrps(lgrpcookie);
return nlgrps;
}
*/
import "C"
// IsCPUSharesAvailable returns whether CPUShares setting is supported.
// We need FSS to be set as default scheduling class to support CPU Shares
func IsCPUSharesAvailable() bool {
cmd := exec.Command("/usr/sbin/dispadmin", "-d")
outBuf := new(bytes.Buffer)
errBuf := new(bytes.Buffer)
cmd.Stderr = errBuf
cmd.Stdout = outBuf
if err := cmd.Run(); err != nil {
return false
}
return (strings.Contains(outBuf.String(), "FSS"))
}
// New returns a new SysInfo, using the filesystem to detect which features
// the kernel supports.
//NOTE Solaris: If we change the below capabilities be sure
// to update verifyPlatformContainerSettings() in daemon_solaris.go
func New(quiet bool) *SysInfo {
sysInfo := &SysInfo{}
sysInfo.cgroupMemInfo = setCgroupMem(quiet)
sysInfo.cgroupCPUInfo = setCgroupCPU(quiet)
sysInfo.cgroupBlkioInfo = setCgroupBlkioInfo(quiet)
sysInfo.cgroupCpusetInfo = setCgroupCPUsetInfo(quiet)
sysInfo.IPv4ForwardingDisabled = false
sysInfo.AppArmor = false
return sysInfo
}
// setCgroupMem reads the memory information for Solaris.
func setCgroupMem(quiet bool) cgroupMemInfo {
return cgroupMemInfo{
MemoryLimit: true,
SwapLimit: true,
MemoryReservation: false,
OomKillDisable: false,
MemorySwappiness: false,
KernelMemory: false,
}
}
// setCgroupCPU reads the cpu information for Solaris.
func setCgroupCPU(quiet bool) cgroupCPUInfo {
return cgroupCPUInfo{
CPUShares: true,
CPUCfsPeriod: false,
CPUCfsQuota: true,
CPURealtimePeriod: false,
CPURealtimeRuntime: false,
}
}
// blkio switches are not supported in Solaris.
func setCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
return cgroupBlkioInfo{
BlkioWeight: false,
BlkioWeightDevice: false,
}
}
// setCgroupCPUsetInfo reads the cpuset information for Solaris.
func setCgroupCPUsetInfo(quiet bool) cgroupCpusetInfo {
return cgroupCpusetInfo{
Cpuset: true,
Cpus: getCPUCount(),
Mems: getLgrpCount(),
}
}
func getCPUCount() string {
ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN)
if ncpus <= 0 {
return ""
}
return strconv.FormatInt(int64(ncpus), 16)
}
func getLgrpCount() string {
nlgrps := C.getLgrpCount()
if nlgrps <= 0 {
return ""
}
return strconv.FormatInt(int64(nlgrps), 16)
}

View file

@ -1,129 +0,0 @@
// +build solaris,cgo
package system
import (
"fmt"
"unsafe"
)
// #cgo CFLAGS: -std=c99
// #cgo LDFLAGS: -lkstat
// #include <unistd.h>
// #include <stdlib.h>
// #include <stdio.h>
// #include <kstat.h>
// #include <sys/swap.h>
// #include <sys/param.h>
// struct swaptable *allocSwaptable(int num) {
// struct swaptable *st;
// struct swapent *swapent;
// st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int));
// swapent = st->swt_ent;
// for (int i = 0; i < num; i++,swapent++) {
// swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char));
// }
// st->swt_n = num;
// return st;
//}
// void freeSwaptable (struct swaptable *st) {
// struct swapent *swapent = st->swt_ent;
// for (int i = 0; i < st->swt_n; i++,swapent++) {
// free(swapent->ste_path);
// }
// free(st);
// }
// swapent_t getSwapEnt(swapent_t *ent, int i) {
// return ent[i];
// }
// int64_t getPpKernel() {
// int64_t pp_kernel = 0;
// kstat_ctl_t *ksc;
// kstat_t *ks;
// kstat_named_t *knp;
// kid_t kid;
//
// if ((ksc = kstat_open()) == NULL) {
// return -1;
// }
// if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) {
// return -1;
// }
// if (((kid = kstat_read(ksc, ks, NULL)) == -1) ||
// ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) {
// return -1;
// }
// switch (knp->data_type) {
// case KSTAT_DATA_UINT64:
// pp_kernel = knp->value.ui64;
// break;
// case KSTAT_DATA_UINT32:
// pp_kernel = knp->value.ui32;
// break;
// }
// pp_kernel *= sysconf(_SC_PAGESIZE);
// return (pp_kernel > 0 ? pp_kernel : -1);
// }
import "C"
// Get the system memory info using sysconf same as prtconf
func getTotalMem() int64 {
pagesize := C.sysconf(C._SC_PAGESIZE)
npages := C.sysconf(C._SC_PHYS_PAGES)
return int64(pagesize * npages)
}
func getFreeMem() int64 {
pagesize := C.sysconf(C._SC_PAGESIZE)
npages := C.sysconf(C._SC_AVPHYS_PAGES)
return int64(pagesize * npages)
}
// ReadMemInfo retrieves memory statistics of the host system and returns a
// MemInfo type.
func ReadMemInfo() (*MemInfo, error) {
ppKernel := C.getPpKernel()
MemTotal := getTotalMem()
MemFree := getFreeMem()
SwapTotal, SwapFree, err := getSysSwap()
if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
SwapFree < 0 {
return nil, fmt.Errorf("error getting system memory info %v\n", err)
}
meminfo := &MemInfo{}
// Total memory is total physical memory less than memory locked by kernel
meminfo.MemTotal = MemTotal - int64(ppKernel)
meminfo.MemFree = MemFree
meminfo.SwapTotal = SwapTotal
meminfo.SwapFree = SwapFree
return meminfo, nil
}
func getSysSwap() (int64, int64, error) {
var tSwap int64
var fSwap int64
var diskblksPerPage int64
num, err := C.swapctl(C.SC_GETNSWP, nil)
if err != nil {
return -1, -1, err
}
st := C.allocSwaptable(num)
_, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st))
if err != nil {
C.freeSwaptable(st)
return -1, -1, err
}
diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT)
for i := 0; i < int(num); i++ {
swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i))
tSwap += int64(swapent.ste_pages) * diskblksPerPage
fSwap += int64(swapent.ste_free) * diskblksPerPage
}
C.freeSwaptable(st)
return tSwap, fSwap, nil
}

View file

@ -1,65 +0,0 @@
// +build solaris,cgo
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
// #include <termios.h>
import "C"
// Termios is the Unix API for terminal I/O.
// It is passthrough for unix.Termios in order to make it portable with
// other platforms where it is not available or handled differently.
type Termios unix.Termios
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if err := tcget(fd, &oldState.termios); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON | unix.IXANY)
newState.Oflag &^= unix.OPOST
newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
newState.Cflag &^= (unix.CSIZE | unix.PARENB)
newState.Cflag |= unix.CS8
/*
VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned
Since VMIN is overloaded with another element in canonical mode when we switch modes it defaults to 4. It
needs to be explicitly set to 1.
*/
newState.Cc[C.VMIN] = 1
newState.Cc[C.VTIME] = 0
if err := tcset(fd, &newState); err != 0 {
return nil, err
}
return &oldState, nil
}
func tcget(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}

View file

@ -1,42 +0,0 @@
// +build solaris,cgo
package term
import (
"unsafe"
"golang.org/x/sys/unix"
)
/*
#include <unistd.h>
#include <stropts.h>
#include <termios.h>
// Small wrapper to get rid of variadic args of ioctl()
int my_ioctl(int fd, int cmd, struct winsize *ws) {
return ioctl(fd, cmd, ws);
}
*/
import "C"
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return ws, nil
}
return ws, err
}
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return nil
}
return err
}

View file

@ -1,7 +1,5 @@
// +build !solaris
// TODO: Support Solaris
package registry
import (

View file

@ -28,11 +28,6 @@ func TestDecodeContainerConfig(t *testing.T) {
image string
)
//TODO: Should run for Solaris
if runtime.GOOS == "solaris" {
t.Skip()
}
if runtime.GOOS != "windows" {
image = "ubuntu"
fixtures = []f{

View file

@ -1,46 +0,0 @@
package runconfig
import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/sysinfo"
)
// DefaultDaemonNetworkMode returns the default network stack the daemon should
// use.
func DefaultDaemonNetworkMode() container.NetworkMode {
return container.NetworkMode("bridge")
}
// IsPreDefinedNetwork indicates if a network is predefined by the daemon
func IsPreDefinedNetwork(network string) bool {
return false
}
// validateNetMode ensures that the various combinations of requested
// network settings are valid.
func validateNetMode(c *container.Config, hc *container.HostConfig) error {
// We may not be passed a host config, such as in the case of docker commit
return nil
}
// validateIsolation performs platform specific validation of the
// isolation level in the hostconfig structure.
// This setting is currently discarded for Solaris so this is a no-op.
func validateIsolation(hc *container.HostConfig) error {
return nil
}
// validateQoS performs platform specific validation of the QoS settings
func validateQoS(hc *container.HostConfig) error {
return nil
}
// validateResources performs platform specific validation of the resource settings
func validateResources(hc *container.HostConfig, si *sysinfo.SysInfo) error {
return nil
}
// validatePrivileged performs platform specific validation of the Privileged setting
func validatePrivileged(hc *container.HostConfig) error {
return nil
}

View file

@ -181,7 +181,7 @@ func TestValidateName(t *testing.T) {
}
func TestCreateWithOpts(t *testing.T) {
if runtime.GOOS == "windows" || runtime.GOOS == "solaris" {
if runtime.GOOS == "windows" {
t.Skip()
}
rootDir, err := ioutil.TempDir("", "local-volume-test")