Merge pull request #35285 from crosbymichael/solaris
Remove solaris files
This commit is contained in:
commit
17bb1d3663
41 changed files with 14 additions and 1776 deletions
|
@ -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
|
|
@ -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{}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
FROM solaris
|
||||
EXPOSE 80/tcp
|
||||
COPY httpserver .
|
||||
CMD ["./httpserver"]
|
|
@ -1,5 +0,0 @@
|
|||
// +build solaris
|
||||
|
||||
package daemon
|
||||
|
||||
const bindMountType = "lofs"
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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")
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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{}) {
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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,
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
// +build !solaris
|
||||
|
||||
// TODO: Support Solaris
|
||||
|
||||
package registry
|
||||
|
||||
import (
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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")
|
||||
|
|
Loading…
Reference in a new issue