Browse code

Get the Docker Engine to build clean on Solaris

Signed-off-by: Amit Krishnan <krish.amit@gmail.com>

Amit Krishnan authored on 2016/03/26 08:38:00
Showing 61 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,74 @@
0
+// +build solaris
1
+
2
+package main
3
+
4
+import (
5
+	"fmt"
6
+	"net"
7
+	"os"
8
+	"path/filepath"
9
+	"syscall"
10
+
11
+	"github.com/docker/docker/libcontainerd"
12
+	"github.com/docker/docker/pkg/system"
13
+)
14
+
15
+const defaultDaemonConfigFile = ""
16
+
17
+// currentUserIsOwner checks whether the current user is the owner of the given
18
+// file.
19
+func currentUserIsOwner(f string) bool {
20
+	if fileInfo, err := system.Stat(f); err == nil && fileInfo != nil {
21
+		if int(fileInfo.UID()) == os.Getuid() {
22
+			return true
23
+		}
24
+	}
25
+	return false
26
+}
27
+
28
+// setDefaultUmask sets the umask to 0022 to avoid problems
29
+// caused by custom umask
30
+func setDefaultUmask() error {
31
+	desiredUmask := 0022
32
+	syscall.Umask(desiredUmask)
33
+	if umask := syscall.Umask(desiredUmask); umask != desiredUmask {
34
+		return fmt.Errorf("failed to set umask: expected %#o, got %#o", desiredUmask, umask)
35
+	}
36
+
37
+	return nil
38
+}
39
+
40
+func getDaemonConfDir() string {
41
+	return "/etc/docker"
42
+}
43
+
44
+// setupConfigReloadTrap configures the USR2 signal to reload the configuration.
45
+func (cli *DaemonCli) setupConfigReloadTrap() {
46
+}
47
+
48
+// notifySystem sends a message to the host when the server is ready to be used
49
+func notifySystem() {
50
+}
51
+
52
+func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
53
+	opts := []libcontainerd.RemoteOption{}
54
+	return opts
55
+}
56
+
57
+// getLibcontainerdRoot gets the root directory for libcontainerd/containerd to
58
+// store their state.
59
+func (cli *DaemonCli) getLibcontainerdRoot() string {
60
+	return filepath.Join(cli.Config.ExecRoot, "libcontainerd")
61
+}
62
+
63
+func allocateDaemonPort(addr string) error {
64
+	return nil
65
+}
66
+
67
+// notifyShutdown is called after the daemon shuts down but before the process exits.
68
+func notifyShutdown(err error) {
69
+}
70
+
71
+func wrapListeners(proto string, ls []net.Listener) []net.Listener {
72
+	return ls
73
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !windows
1
+// +build !windows,!solaris
2 2
 
3 3
 package main
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,95 @@
0
+// +build solaris
1
+
2
+package container
3
+
4
+import (
5
+	"os"
6
+	"path/filepath"
7
+
8
+	"github.com/docker/docker/volume"
9
+	"github.com/docker/engine-api/types/container"
10
+)
11
+
12
+// Container holds fields specific to the Solaris implementation. See
13
+// CommonContainer for standard fields common to all containers.
14
+type Container struct {
15
+	CommonContainer
16
+
17
+	// fields below here are platform specific.
18
+	HostnamePath   string
19
+	HostsPath      string
20
+	ResolvConfPath string
21
+}
22
+
23
+// ExitStatus provides exit reasons for a container.
24
+type ExitStatus struct {
25
+	// The exit code with which the container exited.
26
+	ExitCode int
27
+}
28
+
29
+// CreateDaemonEnvironment creates a new environment variable slice for this container.
30
+func (container *Container) CreateDaemonEnvironment(linkedEnv []string) []string {
31
+	return nil
32
+}
33
+
34
+func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
35
+	return volumeMounts, nil
36
+}
37
+
38
+// TrySetNetworkMount attempts to set the network mounts given a provided destination and
39
+// the path to use for it; return true if the given destination was a network mount file
40
+func (container *Container) TrySetNetworkMount(destination string, path string) bool {
41
+	return true
42
+}
43
+
44
+// NetworkMounts returns the list of network mounts.
45
+func (container *Container) NetworkMounts() []Mount {
46
+	var mount []Mount
47
+	return mount
48
+}
49
+
50
+// CopyImagePathContent copies files in destination to the volume.
51
+func (container *Container) CopyImagePathContent(v volume.Volume, destination string) error {
52
+	return nil
53
+}
54
+
55
+// UnmountIpcMounts unmount Ipc related mounts.
56
+func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
57
+}
58
+
59
+// IpcMounts returns the list of Ipc related mounts.
60
+func (container *Container) IpcMounts() []Mount {
61
+	return nil
62
+}
63
+
64
+// UpdateContainer updates configuration of a container
65
+func (container *Container) UpdateContainer(hostConfig *container.HostConfig) error {
66
+	return nil
67
+}
68
+
69
+// UnmountVolumes explicitly unmounts volumes from the container.
70
+func (container *Container) UnmountVolumes(forceSyscall bool, volumeEventLog func(name, action string, attributes map[string]string)) error {
71
+	return nil
72
+}
73
+
74
+// TmpfsMounts returns the list of tmpfs mounts
75
+func (container *Container) TmpfsMounts() []Mount {
76
+	var mounts []Mount
77
+	return mounts
78
+}
79
+
80
+// cleanResourcePath cleans a resource path and prepares to combine with mnt path
81
+func cleanResourcePath(path string) string {
82
+	return filepath.Join(string(os.PathSeparator), path)
83
+}
84
+
85
+// BuildHostnameFile writes the container's hostname file.
86
+func (container *Container) BuildHostnameFile() error {
87
+	return nil
88
+}
89
+
90
+// canMountFS determines if the file system for the container
91
+// can be mounted locally. A no-op on non-Windows platforms
92
+func (container *Container) canMountFS() bool {
93
+	return true
94
+}
0 95
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+package container
1
+
2
+// setFromExitStatus is a platform specific helper function to set the state
3
+// based on the ExitStatus structure.
4
+func (s *State) setFromExitStatus(exitStatus *ExitStatus) {
5
+	s.ExitCode = exitStatus.ExitCode
6
+}
0 7
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+package daemon
1
+
2
+import (
3
+	flag "github.com/docker/docker/pkg/mflag"
4
+)
5
+
6
+var (
7
+	defaultPidFile = "/var/run/docker.pid"
8
+	defaultGraph   = "/var/lib/docker"
9
+	defaultExec    = "zones"
10
+)
11
+
12
+// Config defines the configuration of a docker daemon.
13
+// These are the configuration settings that you pass
14
+// to the docker daemon when you launch it with say: `docker -d -e lxc`
15
+type Config struct {
16
+	CommonConfig
17
+
18
+	// Fields below here are platform specific.
19
+	ExecRoot string `json:"exec-root,omitempty"`
20
+}
21
+
22
+// bridgeConfig stores all the bridge driver specific
23
+// configuration.
24
+type bridgeConfig struct {
25
+	commonBridgeConfig
26
+}
27
+
28
+// InstallFlags adds command-line options to the top-level flag parser for
29
+// the current process.
30
+// Subsequent calls to `flag.Parse` will populate config with values parsed
31
+// from the command-line.
32
+func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
33
+	// First handle install flags which are consistent cross-platform
34
+	config.InstallCommonFlags(cmd, usageFn)
35
+
36
+	// Then platform-specific install flags
37
+	config.attachExperimentalFlags(cmd, usageFn)
38
+}
0 39
new file mode 100644
... ...
@@ -0,0 +1,50 @@
0
+// +build solaris
1
+
2
+package daemon
3
+
4
+import (
5
+	"fmt"
6
+
7
+	"github.com/docker/docker/container"
8
+	networktypes "github.com/docker/engine-api/types/network"
9
+	"github.com/docker/libnetwork"
10
+)
11
+
12
+func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
13
+	return nil, nil
14
+}
15
+
16
+// ConnectToNetwork connects a container to a network
17
+func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
18
+	return fmt.Errorf("Solaris does not support connecting a running container to a network")
19
+}
20
+
21
+// getSize returns real size & virtual size
22
+func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
23
+	return 0, 0
24
+}
25
+
26
+// DisconnectFromNetwork disconnects a container from the network
27
+func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error {
28
+	return fmt.Errorf("Solaris does not support disconnecting a running container from a network")
29
+}
30
+
31
+func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
32
+	return nil
33
+}
34
+
35
+func (daemon *Daemon) mountVolumes(container *container.Container) error {
36
+	return nil
37
+}
38
+
39
+func killProcessDirectly(container *container.Container) error {
40
+	return nil
41
+}
42
+
43
+func detachMounted(path string) error {
44
+	return nil
45
+}
46
+
47
+func isLinkable(child *container.Container) bool {
48
+	return false
49
+}
... ...
@@ -799,7 +799,7 @@ func NewDaemon(config *Config, registryService *registry.Service, containerdRemo
799 799
 	sysInfo := sysinfo.New(false)
800 800
 	// Check if Devices cgroup is mounted, it is hard requirement for container security,
801 801
 	// on Linux/FreeBSD.
802
-	if runtime.GOOS != "windows" && !sysInfo.CgroupDevicesEnabled {
802
+	if runtime.GOOS != "windows" && runtime.GOOS != "solaris" && !sysInfo.CgroupDevicesEnabled {
803 803
 		return nil, fmt.Errorf("Devices cgroup isn't mounted")
804 804
 	}
805 805
 
806 806
new file mode 100644
... ...
@@ -0,0 +1,159 @@
0
+// +build solaris,cgo
1
+
2
+package daemon
3
+
4
+import (
5
+	"fmt"
6
+
7
+	"github.com/docker/docker/container"
8
+	"github.com/docker/docker/image"
9
+	"github.com/docker/docker/layer"
10
+	"github.com/docker/docker/pkg/idtools"
11
+	"github.com/docker/docker/pkg/parsers/kernel"
12
+	"github.com/docker/docker/reference"
13
+	"github.com/docker/engine-api/types"
14
+	containertypes "github.com/docker/engine-api/types/container"
15
+	"github.com/docker/libnetwork"
16
+	nwconfig "github.com/docker/libnetwork/config"
17
+)
18
+
19
+//#include <zone.h>
20
+import "C"
21
+
22
+const (
23
+	defaultVirtualSwitch = "Virtual Switch"
24
+	platformSupported    = true
25
+	solarisMinCPUShares  = 1
26
+	solarisMaxCPUShares  = 65535
27
+)
28
+
29
+func (daemon *Daemon) cleanupMountsByID(id string) error {
30
+	return nil
31
+}
32
+
33
+func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
34
+	return nil
35
+}
36
+
37
+func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) {
38
+	return nil, nil, nil
39
+}
40
+
41
+func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
42
+	return nil
43
+}
44
+
45
+// setupInitLayer populates a directory with mountpoints suitable
46
+// for bind-mounting dockerinit into the container. The mountpoint is simply an
47
+// empty file at /.dockerinit
48
+//
49
+// This extra layer is used by all containers as the top-most ro layer. It protects
50
+// the container from unwanted side-effects on the rw layer.
51
+func setupInitLayer(initLayer string, rootUID, rootGID int) error {
52
+	return nil
53
+}
54
+
55
+func checkKernel() error {
56
+	// solaris can rely upon checkSystem() below, we don't skew kernel versions
57
+	return nil
58
+}
59
+
60
+func (daemon *Daemon) getCgroupDriver() string {
61
+	return ""
62
+}
63
+
64
+func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConfig, adjustCPUShares bool) error {
65
+	return nil
66
+}
67
+
68
+// verifyPlatformContainerSettings performs platform-specific validation of the
69
+// hostconfig and config structures.
70
+func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
71
+	warnings := []string{}
72
+	return warnings, nil
73
+}
74
+
75
+// verifyDaemonSettings performs validation of daemon config struct
76
+func verifyDaemonSettings(config *Config) error {
77
+	// checkSystem validates platform-specific requirements
78
+	return nil
79
+}
80
+
81
+func checkSystem() error {
82
+	// check OS version for compatibility, ensure running in global zone
83
+	var err error
84
+	var id C.zoneid_t
85
+
86
+	if id, err = C.getzoneid(); err != nil {
87
+		return fmt.Errorf("Exiting. Error getting zone id: %+v", err)
88
+	}
89
+	if int(id) != 0 {
90
+		return fmt.Errorf("Exiting because the Docker daemon is not running in the global zone")
91
+	}
92
+
93
+	v, err := kernel.GetKernelVersion()
94
+	if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 5, Major: 12, Minor: 0}) < 0 {
95
+		return fmt.Errorf("Your Solaris kernel version: %s doesn't support Docker. Please upgrade to 5.12.0", v.String())
96
+	}
97
+	return err
98
+}
99
+
100
+// configureMaxThreads sets the Go runtime max threads threshold
101
+// which is 90% of the kernel setting from /proc/sys/kernel/threads-max
102
+func configureMaxThreads(config *Config) error {
103
+	return nil
104
+}
105
+
106
+// configureKernelSecuritySupport configures and validate security support for the kernel
107
+func configureKernelSecuritySupport(config *Config, driverName string) error {
108
+	return nil
109
+}
110
+
111
+func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) {
112
+	return nil, nil
113
+}
114
+
115
+// registerLinks sets up links between containers and writes the
116
+// configuration out for persistence.
117
+func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error {
118
+	return nil
119
+}
120
+
121
+func (daemon *Daemon) cleanupMounts() error {
122
+	return nil
123
+}
124
+
125
+// conditionalMountOnStart is a platform specific helper function during the
126
+// container start to call mount.
127
+func (daemon *Daemon) conditionalMountOnStart(container *container.Container) error {
128
+	return nil
129
+}
130
+
131
+// conditionalUnmountOnCleanup is a platform specific helper function called
132
+// during the cleanup of a container to unmount.
133
+func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container) error {
134
+	return daemon.Unmount(container)
135
+}
136
+
137
+func restoreCustomImage(is image.Store, ls layer.Store, rs reference.Store) error {
138
+	// Solaris has no custom images to register
139
+	return nil
140
+}
141
+
142
+func driverOptions(config *Config) []nwconfig.Option {
143
+	return []nwconfig.Option{}
144
+}
145
+
146
+func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
147
+	return nil, nil
148
+}
149
+
150
+// setDefaultIsolation determine the default isolation mode for the
151
+// daemon to run in. This is only applicable on Windows
152
+func (daemon *Daemon) setDefaultIsolation() error {
153
+	return nil
154
+}
155
+
156
+func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
157
+	return types.RootFS{}
158
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!freebsd,!windows
1
+// +build !linux,!freebsd,!windows,!solaris
2 2
 
3 3
 package daemon
4 4
 
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!darwin,!freebsd,!windows
1
+// +build !linux,!darwin,!freebsd,!windows,!solaris
2 2
 
3 3
 package daemon
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+package daemon
1
+
2
+import (
3
+	"github.com/docker/docker/container"
4
+	"github.com/docker/docker/daemon/exec"
5
+	"github.com/docker/docker/libcontainerd"
6
+)
7
+
8
+func execSetPlatformOpt(c *container.Container, ec *exec.Config, p *libcontainerd.Process) error {
9
+	return nil
10
+}
0 11
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+// +build solaris,cgo
1
+
2
+package graphdriver
3
+
4
+/*
5
+#include <sys/statvfs.h>
6
+#include <stdlib.h>
7
+
8
+static inline struct statvfs *getstatfs(char *s) {
9
+        struct statvfs *buf;
10
+        int err;
11
+        buf = (struct statvfs *)malloc(sizeof(struct statvfs));
12
+        err = statvfs(s, buf);
13
+        return buf;
14
+}
15
+*/
16
+import "C"
17
+import (
18
+	"path/filepath"
19
+	"unsafe"
20
+
21
+	log "github.com/Sirupsen/logrus"
22
+)
23
+
24
+const (
25
+	// FsMagicZfs filesystem id for Zfs
26
+	FsMagicZfs = FsMagic(0x2fc12fc1)
27
+)
28
+
29
+var (
30
+	// Slice of drivers that should be used in an order
31
+	priority = []string{
32
+		"zfs",
33
+	}
34
+
35
+	// FsNames maps filesystem id to name of the filesystem.
36
+	FsNames = map[FsMagic]string{
37
+		FsMagicZfs: "zfs",
38
+	}
39
+)
40
+
41
+// GetFSMagic returns the filesystem id given the path.
42
+func GetFSMagic(rootpath string) (FsMagic, error) {
43
+	return 0, nil
44
+}
45
+
46
+// Mounted checks if the given path is mounted as the fs type
47
+//Solaris supports only ZFS for now
48
+func Mounted(fsType FsMagic, mountPath string) (bool, error) {
49
+
50
+	cs := C.CString(filepath.Dir(mountPath))
51
+	buf := C.getstatfs(cs)
52
+
53
+	// on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
54
+	if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
55
+		(buf.f_basetype[3] != 0) {
56
+		log.Debugf("[zfs] no zfs dataset found for rootdir '%s'", mountPath)
57
+		C.free(unsafe.Pointer(buf))
58
+		return false, ErrPrerequisites
59
+	}
60
+
61
+	C.free(unsafe.Pointer(buf))
62
+	C.free(unsafe.Pointer(cs))
63
+	return true, nil
64
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!windows,!freebsd
1
+// +build !linux,!windows,!freebsd,!solaris
2 2
 
3 3
 package graphdriver
4 4
 
... ...
@@ -1,4 +1,4 @@
1
-// +build !exclude_graphdriver_zfs,linux !exclude_graphdriver_zfs,freebsd
1
+// +build !exclude_graphdriver_zfs,linux !exclude_graphdriver_zfs,freebsd, solaris
2 2
 
3 3
 package register
4 4
 
... ...
@@ -1,4 +1,4 @@
1
-// +build linux freebsd
1
+// +build linux freebsd solaris
2 2
 
3 3
 package zfs
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,59 @@
0
+// +build solaris,cgo
1
+
2
+package zfs
3
+
4
+/*
5
+#include <sys/statvfs.h>
6
+#include <stdlib.h>
7
+
8
+static inline struct statvfs *getstatfs(char *s) {
9
+        struct statvfs *buf;
10
+        int err;
11
+        buf = (struct statvfs *)malloc(sizeof(struct statvfs));
12
+        err = statvfs(s, buf);
13
+        return buf;
14
+}
15
+*/
16
+import "C"
17
+import (
18
+	"path/filepath"
19
+	"strings"
20
+	"unsafe"
21
+
22
+	log "github.com/Sirupsen/logrus"
23
+	"github.com/docker/docker/daemon/graphdriver"
24
+)
25
+
26
+func checkRootdirFs(rootdir string) error {
27
+
28
+	cs := C.CString(filepath.Dir(rootdir))
29
+	buf := C.getstatfs(cs)
30
+
31
+	// on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
32
+	if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
33
+		(buf.f_basetype[3] != 0) {
34
+		log.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
35
+		C.free(unsafe.Pointer(buf))
36
+		return graphdriver.ErrPrerequisites
37
+	}
38
+
39
+	C.free(unsafe.Pointer(buf))
40
+	C.free(unsafe.Pointer(cs))
41
+	return nil
42
+}
43
+
44
+/* rootfs is introduced to comply with the OCI spec
45
+which states that root filesystem must be mounted at <CID>/rootfs/ instead of <CID>/
46
+*/
47
+func getMountpoint(id string) string {
48
+	maxlen := 12
49
+
50
+	// we need to preserve filesystem suffix
51
+	suffix := strings.SplitN(id, "-", 2)
52
+
53
+	if len(suffix) > 1 {
54
+		return filepath.Join(id[:maxlen]+"-"+suffix[1], "rootfs", "root")
55
+	}
56
+
57
+	return filepath.Join(id[:maxlen], "rootfs", "root")
58
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!freebsd
1
+// +build !linux,!freebsd,!solaris
2 2
 
3 3
 package zfs
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,40 @@
0
+package daemon
1
+
2
+import (
3
+	"github.com/docker/docker/api/types/backend"
4
+	"github.com/docker/docker/container"
5
+	"github.com/docker/docker/daemon/exec"
6
+	"github.com/docker/engine-api/types"
7
+)
8
+
9
+// This sets platform-specific fields
10
+func setPlatformSpecificContainerFields(container *container.Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
11
+	return contJSONBase
12
+}
13
+
14
+// containerInspectPre120 get containers for pre 1.20 APIs.
15
+func (daemon *Daemon) containerInspectPre120(name string) (*types.ContainerJSON, error) {
16
+	return daemon.containerInspectCurrent(name, false)
17
+}
18
+
19
+func addMountPoints(container *container.Container) []types.MountPoint {
20
+	mountPoints := make([]types.MountPoint, 0, len(container.MountPoints))
21
+	for _, m := range container.MountPoints {
22
+		mountPoints = append(mountPoints, types.MountPoint{
23
+			Name:        m.Name,
24
+			Source:      m.Path(),
25
+			Destination: m.Destination,
26
+			Driver:      m.Driver,
27
+			RW:          m.RW,
28
+		})
29
+	}
30
+	return mountPoints
31
+}
32
+
33
+func inspectExecProcessConfig(e *exec.Config) *backend.ExecProcessConfig {
34
+	return &backend.ExecProcessConfig{
35
+		Tty:        e.Tty,
36
+		Entrypoint: e.Entrypoint,
37
+		Arguments:  e.Args,
38
+	}
39
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !windows
1
+// +build !windows,!solaris
2 2
 
3 3
 package daemon
4 4
 
... ...
@@ -1,4 +1,4 @@
1
-// +build linux freebsd
1
+// +build linux freebsd solaris
2 2
 
3 3
 package daemon
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+package daemon
1
+
2
+import (
3
+	"github.com/docker/docker/container"
4
+	"github.com/docker/docker/libcontainerd"
5
+)
6
+
7
+// platformConstructExitStatus returns a platform specific exit status structure
8
+func platformConstructExitStatus(e libcontainerd.StateInfo) *container.ExitStatus {
9
+	return &container.ExitStatus{
10
+		ExitCode: int(e.ExitCode),
11
+	}
12
+}
13
+
14
+// postRunProcessing perfoms any processing needed on the container after it has stopped.
15
+func (daemon *Daemon) postRunProcessing(container *container.Container, e libcontainerd.StateInfo) error {
16
+	return nil
17
+}
0 18
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+package daemon
1
+
2
+import (
3
+	"github.com/docker/docker/container"
4
+	"github.com/docker/docker/libcontainerd"
5
+	"github.com/docker/docker/oci"
6
+)
7
+
8
+func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, error) {
9
+	s := oci.DefaultSpec()
10
+	return (*libcontainerd.Spec)(&s), nil
11
+}
0 12
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+package daemon
1
+
2
+import (
3
+	"github.com/docker/docker/container"
4
+	"time"
5
+)
6
+
7
+// newStatsCollector returns a new statsCollector for collection stats
8
+// for a registered container at the specified interval. The collector allows
9
+// non-running containers to be added and will start processing stats when
10
+// they are started.
11
+func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector {
12
+	return &statsCollector{}
13
+}
14
+
15
+// statsCollector manages and provides container resource stats
16
+type statsCollector struct {
17
+}
18
+
19
+// collect registers the container with the collector and adds it to
20
+// the event loop for collection on the specified interval returning
21
+// a channel for the subscriber to receive on.
22
+func (s *statsCollector) collect(c *container.Container) chan interface{} {
23
+	return nil
24
+}
25
+
26
+// stopCollection closes the channels for all subscribers and removes
27
+// the container from metrics collection.
28
+func (s *statsCollector) stopCollection(c *container.Container) {
29
+}
30
+
31
+// unsubscribe removes a specific subscriber from receiving updates for a container's stats.
32
+func (s *statsCollector) unsubscribe(c *container.Container, ch chan interface{}) {
33
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !windows
1
+// +build !windows,!solaris
2 2
 
3 3
 package daemon
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+package daemon
1
+
2
+import (
3
+	"github.com/docker/docker/libcontainerd"
4
+	"github.com/docker/engine-api/types/container"
5
+)
6
+
7
+func toContainerdResources(resources container.Resources) libcontainerd.Resources {
8
+	var r libcontainerd.Resources
9
+	return r
10
+}
... ...
@@ -93,7 +93,7 @@ if command -v git &> /dev/null && [ -d .git ] && git rev-parse &> /dev/null; the
93 93
 		git status --porcelain --untracked-files=no
94 94
 		echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
95 95
 	fi
96
-	! BUILDTIME=$(date --rfc-3339 ns | sed -e 's/ /T/') &> /dev/null
96
+	! BUILDTIME=$(date --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/') &> /dev/null
97 97
 	if [ -z $BUILDTIME ]; then
98 98
 		# If using bash 3.1 which doesn't support --rfc-3389, eg Windows CI
99 99
 		BUILDTIME=$(date -u)
... ...
@@ -113,6 +113,12 @@ if [ "$AUTO_GOPATH" ]; then
113 113
 	mkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"
114 114
 	ln -sf ../../../.. .gopath/src/"${DOCKER_PKG}"
115 115
 	export GOPATH="${PWD}/.gopath:${PWD}/vendor"
116
+
117
+	if [ "$(go env GOOS)" = 'solaris' ]; then
118
+		# sys/unix is installed outside the standard library on solaris
119
+		# TODO need to allow for version change, need to get version from go
120
+		export GOPATH="${GOPATH}:/usr/lib/gocode/1.5"
121
+	fi
116 122
 fi
117 123
 
118 124
 if [ ! "$GOPATH" ]; then
... ...
@@ -1,4 +1,4 @@
1
-// +build linux freebsd darwin openbsd
1
+// +build linux freebsd darwin openbsd solaris
2 2
 
3 3
 package layer
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,56 @@
0
+package libcontainerd
1
+
2
+type client struct {
3
+	clientCommon
4
+
5
+	// Platform specific properties below here.
6
+}
7
+
8
+func (clnt *client) AddProcess(containerID, processFriendlyName string, specp Process) error {
9
+	return nil
10
+}
11
+
12
+func (clnt *client) Create(containerID string, spec Spec, options ...CreateOption) (err error) {
13
+	return nil
14
+}
15
+
16
+func (clnt *client) Signal(containerID string, sig int) error {
17
+	return nil
18
+}
19
+
20
+func (clnt *client) Resize(containerID, processFriendlyName string, width, height int) error {
21
+	return nil
22
+}
23
+
24
+func (clnt *client) Pause(containerID string) error {
25
+	return nil
26
+}
27
+
28
+func (clnt *client) Resume(containerID string) error {
29
+	return nil
30
+}
31
+
32
+func (clnt *client) Stats(containerID string) (*Stats, error) {
33
+	return nil, nil
34
+}
35
+
36
+// Restore is the handler for restoring a container
37
+func (clnt *client) Restore(containerID string, unusedOnWindows ...CreateOption) error {
38
+	return nil
39
+}
40
+
41
+func (clnt *client) GetPidsForContainer(containerID string) ([]int, error) {
42
+	return nil, nil
43
+}
44
+
45
+// Summary returns a summary of the processes running in a container.
46
+func (clnt *client) Summary(containerID string) ([]Summary, error) {
47
+	return nil, nil
48
+}
49
+
50
+// UpdateResources updates resources for a running container.
51
+func (clnt *client) UpdateResources(containerID string, resources Resources) error {
52
+	// Updating resource isn't supported on Solaris
53
+	// but we should return nil for enabling updating container
54
+	return nil
55
+}
0 56
new file mode 100644
... ...
@@ -0,0 +1,5 @@
0
+package libcontainerd
1
+
2
+type container struct {
3
+	containerCommon
4
+}
0 5
new file mode 100644
... ...
@@ -0,0 +1,6 @@
0
+package libcontainerd
1
+
2
+// process keeps the state for both main container process and exec process.
3
+type process struct {
4
+	processCommon
5
+}
0 6
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+package libcontainerd
1
+
2
+import "github.com/docker/docker/pkg/locker"
3
+
4
+type remote struct {
5
+}
6
+
7
+func (r *remote) Client(b Backend) (Client, error) {
8
+	c := &client{
9
+		clientCommon: clientCommon{
10
+			backend:    b,
11
+			containers: make(map[string]*container),
12
+			locker:     locker.New(),
13
+		},
14
+	}
15
+	return c, nil
16
+}
17
+
18
+func (r *remote) Cleanup() {
19
+}
20
+
21
+// New creates a fresh instance of libcontainerd remote.
22
+func New(_ string, _ ...RemoteOption) (Remote, error) {
23
+	return &remote{}, nil
24
+}
0 25
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+package libcontainerd
1
+
2
+import (
3
+	"github.com/opencontainers/specs/specs-go"
4
+)
5
+
6
+// Spec is the base configuration for the container.  It specifies platform
7
+// independent configuration. This information must be included when the
8
+// bundle is packaged for distribution.
9
+type Spec specs.Spec
10
+
11
+// Process contains information to start a specific application inside the container.
12
+type Process struct {
13
+	// Terminal creates an interactive terminal for the container.
14
+	Terminal bool `json:"terminal"`
15
+	// Args specifies the binary and arguments for the application to execute.
16
+	Args []string `json:"args"`
17
+}
18
+
19
+// Stats contains a stats properties from containerd.
20
+type Stats struct{}
21
+
22
+// Summary container a container summary from containerd
23
+type Summary struct{}
24
+
25
+// StateInfo contains description about the new state container has entered.
26
+type StateInfo struct {
27
+	CommonStateInfo
28
+
29
+	// Platform specific StateInfo
30
+}
31
+
32
+// User specifies Solaris specific user and group information for the container's
33
+// main process.
34
+type User specs.User
35
+
36
+// Resources defines updatable container resource values.
37
+type Resources struct{}
0 38
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+package oci
1
+
2
+import (
3
+	"github.com/opencontainers/specs/specs-go"
4
+)
5
+
6
+// DefaultSpec returns default oci spec used by docker.
7
+func DefaultSpec() specs.Spec {
8
+	s := specs.Spec{}
9
+	return s
10
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build linux freebsd
1
+// +build linux freebsd solaris
2 2
 
3 3
 package directory
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+package fileutils
1
+
2
+// GetTotalUsedFds Returns the number of used File Descriptors.
3
+// On Solaris these limits are per process and not systemwide
4
+func GetTotalUsedFds() int {
5
+	return -1
6
+}
0 7
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+package listeners
1
+
2
+import (
3
+	"crypto/tls"
4
+	"fmt"
5
+	"net"
6
+
7
+	"github.com/docker/go-connections/sockets"
8
+)
9
+
10
+// Init creates new listeners for the server.
11
+func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) (ls []net.Listener, err error) {
12
+	switch proto {
13
+	case "tcp":
14
+		l, err := sockets.NewTCPSocket(addr, tlsConfig)
15
+		if err != nil {
16
+			return nil, err
17
+		}
18
+		ls = append(ls, l)
19
+	case "unix":
20
+		l, err := sockets.NewUnixSocket(addr, socketGroup)
21
+		if err != nil {
22
+			return nil, fmt.Errorf("can't create unix socket %s: %v", addr, err)
23
+		}
24
+		ls = append(ls, l)
25
+	default:
26
+		return nil, fmt.Errorf("Invalid protocol format: %q", proto)
27
+	}
28
+
29
+	return
30
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !windows
1
+// +build !windows,!solaris
2 2
 
3 3
 package listeners
4 4
 
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!freebsd freebsd,!cgo
1
+// +build !linux,!freebsd freebsd,!cgo solaris,!cgo
2 2
 
3 3
 package mount
4 4
 
... ...
@@ -9,8 +9,8 @@ func GetMounts() ([]*Info, error) {
9 9
 	return parseMountTable()
10 10
 }
11 11
 
12
-// Mounted looks at /proc/self/mountinfo to determine of the specified
13
-// mountpoint has been mounted
12
+// Mounted determines if a specified mountpoint has been mounted.
13
+// On Linux it looks at /proc/self/mountinfo and on Solaris at mnttab.
14 14
 func Mounted(mountpoint string) (bool, error) {
15 15
 	entries, err := parseMountTable()
16 16
 	if err != nil {
17 17
new file mode 100644
... ...
@@ -0,0 +1,33 @@
0
+// +build solaris,cgo
1
+
2
+package mount
3
+
4
+import (
5
+	"golang.org/x/sys/unix"
6
+	"unsafe"
7
+)
8
+
9
+// #include <stdlib.h>
10
+// #include <stdio.h>
11
+// #include <sys/mount.h>
12
+// int Mount(const char *spec, const char *dir, int mflag,
13
+// char *fstype, char *dataptr, int datalen, char *optptr, int optlen) {
14
+//     return mount(spec, dir, mflag, fstype, dataptr, datalen, optptr, optlen);
15
+// }
16
+import "C"
17
+
18
+func mount(device, target, mType string, flag uintptr, data string) error {
19
+	spec := C.CString(device)
20
+	dir := C.CString(target)
21
+	fstype := C.CString(mType)
22
+	_, err := C.Mount(spec, dir, C.int(flag), fstype, nil, 0, nil, 0)
23
+	C.free(unsafe.Pointer(spec))
24
+	C.free(unsafe.Pointer(dir))
25
+	C.free(unsafe.Pointer(fstype))
26
+	return err
27
+}
28
+
29
+func unmount(target string, flag int) error {
30
+	err := unix.Unmount(target, flag)
31
+	return err
32
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!freebsd freebsd,!cgo
1
+// +build !linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
2 2
 
3 3
 package mount
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,37 @@
0
+// +build solaris,cgo
1
+
2
+package mount
3
+
4
+/*
5
+#include <stdio.h>
6
+#include <sys/mnttab.h>
7
+*/
8
+import "C"
9
+
10
+import (
11
+	"fmt"
12
+)
13
+
14
+func parseMountTable() ([]*Info, error) {
15
+	mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r"))
16
+	if mnttab == nil {
17
+		return nil, fmt.Errorf("Failed to open %s", C.MNTTAB)
18
+	}
19
+
20
+	var out []*Info
21
+	var mp C.struct_mnttab
22
+
23
+	ret := C.getmntent(mnttab, &mp)
24
+	for ret == 0 {
25
+		var mountinfo Info
26
+		mountinfo.Mountpoint = C.GoString(mp.mnt_mountp)
27
+		mountinfo.Source = C.GoString(mp.mnt_special)
28
+		mountinfo.Fstype = C.GoString(mp.mnt_fstype)
29
+		mountinfo.Opts = C.GoString(mp.mnt_mntopts)
30
+		out = append(out, &mountinfo)
31
+		ret = C.getmntent(mnttab, &mp)
32
+	}
33
+
34
+	C.fclose(mnttab)
35
+	return out, nil
36
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !windows,!linux,!freebsd freebsd,!cgo
1
+// +build !windows,!linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
2 2
 
3 3
 package mount
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,14 @@
0
+package kernel
1
+
2
+import (
3
+	"golang.org/x/sys/unix"
4
+)
5
+
6
+func uname() (*unix.Utsname, error) {
7
+	uts := &unix.Utsname{}
8
+
9
+	if err := unix.Uname(uts); err != nil {
10
+		return nil, err
11
+	}
12
+	return uts, nil
13
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux
1
+// +build !linux,!solaris
2 2
 
3 3
 package kernel
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,37 @@
0
+// +build solaris,cgo
1
+
2
+package operatingsystem
3
+
4
+/*
5
+#include <zone.h>
6
+*/
7
+import "C"
8
+
9
+import (
10
+	"bytes"
11
+	"errors"
12
+	"io/ioutil"
13
+)
14
+
15
+var etcOsRelease = "/etc/release"
16
+
17
+// GetOperatingSystem gets the name of the current operating system.
18
+func GetOperatingSystem() (string, error) {
19
+	b, err := ioutil.ReadFile(etcOsRelease)
20
+	if err != nil {
21
+		return "", err
22
+	}
23
+	if i := bytes.Index(b, []byte("\n")); i >= 0 {
24
+		b = bytes.Trim(b[:i], " ")
25
+		return string(b), nil
26
+	}
27
+	return "", errors.New("release not found")
28
+}
29
+
30
+// IsContainerized returns true if we are running inside a container.
31
+func IsContainerized() (bool, error) {
32
+	if C.getzoneid() != 0 {
33
+		return true, nil
34
+	}
35
+	return false, nil
36
+}
0 37
deleted file mode 100644
... ...
@@ -1,15 +0,0 @@
1
-package platform
2
-
3
-import (
4
-	"os/exec"
5
-)
6
-
7
-// runtimeArchitecture gets the name of the current architecture (x86, x86_64, …)
8
-func runtimeArchitecture() (string, error) {
9
-	cmd := exec.Command("uname", "-m")
10
-	machine, err := cmd.Output()
11
-	if err != nil {
12
-		return "", err
13
-	}
14
-	return string(machine), nil
15
-}
16 1
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+// +build freebsd solaris
1
+
2
+package platform
3
+
4
+import (
5
+	"os/exec"
6
+	"strings"
7
+)
8
+
9
+// runtimeArchitecture get the name of the current architecture (i86pc, sun4v)
10
+func runtimeArchitecture() (string, error) {
11
+	cmd := exec.Command("/usr/bin/uname", "-m")
12
+	machine, err := cmd.Output()
13
+	if err != nil {
14
+		return "", err
15
+	}
16
+	return strings.TrimSpace(string(machine)), nil
17
+}
0 18
deleted file mode 100644
... ...
@@ -1,23 +0,0 @@
1
-// +build freebsd
2
-
3
-package reexec
4
-
5
-import (
6
-	"os/exec"
7
-)
8
-
9
-// Self returns the path to the current process's binary.
10
-// Uses os.Args[0].
11
-func Self() string {
12
-	return naiveSelf()
13
-}
14
-
15
-// Command returns *exec.Cmd which have Path as current binary.
16
-// For example if current binary is "docker" at "/usr/bin/", then cmd.Path will
17
-// be set to "/usr/bin/docker".
18
-func Command(args ...string) *exec.Cmd {
19
-	return &exec.Cmd{
20
-		Path: Self(),
21
-		Args: args,
22
-	}
23
-}
24 1
new file mode 100644
... ...
@@ -0,0 +1,23 @@
0
+// +build freebsd solaris
1
+
2
+package reexec
3
+
4
+import (
5
+	"os/exec"
6
+)
7
+
8
+// Self returns the path to the current process's binary.
9
+// Uses os.Args[0].
10
+func Self() string {
11
+	return naiveSelf()
12
+}
13
+
14
+// Command returns *exec.Cmd which have Path as current binary.
15
+// For example if current binary is "docker" at "/usr/bin/", then cmd.Path will
16
+// be set to "/usr/bin/docker".
17
+func Command(args ...string) *exec.Cmd {
18
+	return &exec.Cmd{
19
+		Path: Self(),
20
+		Args: args,
21
+	}
22
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!windows,!freebsd
1
+// +build !linux,!windows,!freebsd,!solaris
2 2
 
3 3
 package reexec
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+package signal
1
+
2
+import (
3
+	"syscall"
4
+)
5
+
6
+// SignalMap is a map of Solaris signals.
7
+// SIGINFO and SIGTHR not defined for Solaris
8
+var SignalMap = map[string]syscall.Signal{
9
+	"ABRT":   syscall.SIGABRT,
10
+	"ALRM":   syscall.SIGALRM,
11
+	"BUF":    syscall.SIGBUS,
12
+	"CHLD":   syscall.SIGCHLD,
13
+	"CONT":   syscall.SIGCONT,
14
+	"EMT":    syscall.SIGEMT,
15
+	"FPE":    syscall.SIGFPE,
16
+	"HUP":    syscall.SIGHUP,
17
+	"ILL":    syscall.SIGILL,
18
+	"INT":    syscall.SIGINT,
19
+	"IO":     syscall.SIGIO,
20
+	"IOT":    syscall.SIGIOT,
21
+	"KILL":   syscall.SIGKILL,
22
+	"LWP":    syscall.SIGLWP,
23
+	"PIPE":   syscall.SIGPIPE,
24
+	"PROF":   syscall.SIGPROF,
25
+	"QUIT":   syscall.SIGQUIT,
26
+	"SEGV":   syscall.SIGSEGV,
27
+	"STOP":   syscall.SIGSTOP,
28
+	"SYS":    syscall.SIGSYS,
29
+	"TERM":   syscall.SIGTERM,
30
+	"TRAP":   syscall.SIGTRAP,
31
+	"TSTP":   syscall.SIGTSTP,
32
+	"TTIN":   syscall.SIGTTIN,
33
+	"TTOU":   syscall.SIGTTOU,
34
+	"URG":    syscall.SIGURG,
35
+	"USR1":   syscall.SIGUSR1,
36
+	"USR2":   syscall.SIGUSR2,
37
+	"VTALRM": syscall.SIGVTALRM,
38
+	"WINCH":  syscall.SIGWINCH,
39
+	"XCPU":   syscall.SIGXCPU,
40
+	"XFSZ":   syscall.SIGXFSZ,
41
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!darwin,!freebsd,!windows
1
+// +build !linux,!darwin,!freebsd,!windows,!solaris
2 2
 
3 3
 package signal
4 4
 
5 5
new file mode 100644
... ...
@@ -0,0 +1,119 @@
0
+// +build solaris,cgo
1
+
2
+package sysinfo
3
+
4
+import (
5
+	"bytes"
6
+	"os/exec"
7
+	"strconv"
8
+	"strings"
9
+)
10
+
11
+/*
12
+#cgo LDFLAGS: -llgrp
13
+#include <unistd.h>
14
+#include <stdlib.h>
15
+#include <sys/lgrp_user.h>
16
+int getLgrpCount() {
17
+	lgrp_cookie_t lgrpcookie = LGRP_COOKIE_NONE;
18
+	uint_t nlgrps;
19
+
20
+	if ((lgrpcookie = lgrp_init(LGRP_VIEW_OS)) == LGRP_COOKIE_NONE) {
21
+		return -1;
22
+	}
23
+	nlgrps = lgrp_nlgrps(lgrpcookie);
24
+	return nlgrps;
25
+}
26
+*/
27
+import "C"
28
+
29
+// IsCPUSharesAvailable returns whether CPUShares setting is supported.
30
+// We need FSS to be set as default scheduling class to support CPU Shares
31
+func IsCPUSharesAvailable() bool {
32
+	cmd := exec.Command("/usr/sbin/dispadmin", "-d")
33
+	outBuf := new(bytes.Buffer)
34
+	errBuf := new(bytes.Buffer)
35
+	cmd.Stderr = errBuf
36
+	cmd.Stdout = outBuf
37
+
38
+	if err := cmd.Run(); err != nil {
39
+		return false
40
+	}
41
+	return (strings.Contains(outBuf.String(), "FSS"))
42
+}
43
+
44
+// New returns a new SysInfo, using the filesystem to detect which features
45
+// the kernel supports.
46
+//NOTE Solaris: If we change the below capabilities be sure
47
+// to update verifyPlatformContainerSettings() in daemon_solaris.go
48
+func New(quiet bool) *SysInfo {
49
+	sysInfo := &SysInfo{}
50
+	sysInfo.cgroupMemInfo = setCgroupMem(quiet)
51
+	sysInfo.cgroupCPUInfo = setCgroupCPU(quiet)
52
+	sysInfo.cgroupBlkioInfo = setCgroupBlkioInfo(quiet)
53
+	sysInfo.cgroupCpusetInfo = setCgroupCPUsetInfo(quiet)
54
+
55
+	sysInfo.IPv4ForwardingDisabled = false
56
+
57
+	sysInfo.AppArmor = false
58
+
59
+	return sysInfo
60
+}
61
+
62
+// setCgroupMem reads the memory information for Solaris.
63
+func setCgroupMem(quiet bool) cgroupMemInfo {
64
+
65
+	return cgroupMemInfo{
66
+		MemoryLimit:       true,
67
+		SwapLimit:         true,
68
+		MemoryReservation: false,
69
+		OomKillDisable:    false,
70
+		MemorySwappiness:  false,
71
+		KernelMemory:      false,
72
+	}
73
+}
74
+
75
+// setCgroupCPU reads the cpu information for Solaris.
76
+func setCgroupCPU(quiet bool) cgroupCPUInfo {
77
+
78
+	return cgroupCPUInfo{
79
+		CPUShares:    true,
80
+		CPUCfsPeriod: false,
81
+		CPUCfsQuota:  true,
82
+	}
83
+}
84
+
85
+// blkio switches are not supported in Solaris.
86
+func setCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
87
+
88
+	return cgroupBlkioInfo{
89
+		BlkioWeight:       false,
90
+		BlkioWeightDevice: false,
91
+	}
92
+}
93
+
94
+// setCgroupCPUsetInfo reads the cpuset information for Solaris.
95
+func setCgroupCPUsetInfo(quiet bool) cgroupCpusetInfo {
96
+
97
+	return cgroupCpusetInfo{
98
+		Cpuset: true,
99
+		Cpus:   getCPUCount(),
100
+		Mems:   getLgrpCount(),
101
+	}
102
+}
103
+
104
+func getCPUCount() string {
105
+	ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN)
106
+	if ncpus <= 0 {
107
+		return ""
108
+	}
109
+	return strconv.FormatInt(int64(ncpus), 16)
110
+}
111
+
112
+func getLgrpCount() string {
113
+	nlgrps := C.getLgrpCount()
114
+	if nlgrps <= 0 {
115
+		return ""
116
+	}
117
+	return strconv.FormatInt(int64(nlgrps), 16)
118
+}
0 119
new file mode 100644
... ...
@@ -0,0 +1,128 @@
0
+// +build solaris,cgo
1
+
2
+package system
3
+
4
+import (
5
+	"fmt"
6
+	"unsafe"
7
+)
8
+
9
+// #cgo LDFLAGS: -lkstat
10
+// #include <unistd.h>
11
+// #include <stdlib.h>
12
+// #include <stdio.h>
13
+// #include <kstat.h>
14
+// #include <sys/swap.h>
15
+// #include <sys/param.h>
16
+// struct swaptable *allocSwaptable(int num) {
17
+//	struct swaptable *st;
18
+//	struct swapent *swapent;
19
+// 	st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int));
20
+//	swapent = st->swt_ent;
21
+//	for (int i = 0; i < num; i++,swapent++) {
22
+//		swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char));
23
+//	}
24
+//	st->swt_n = num;
25
+//	return st;
26
+//}
27
+// void freeSwaptable (struct swaptable *st) {
28
+//	struct swapent *swapent = st->swt_ent;
29
+//	for (int i = 0; i < st->swt_n; i++,swapent++) {
30
+//		free(swapent->ste_path);
31
+//	}
32
+//	free(st);
33
+// }
34
+// swapent_t getSwapEnt(swapent_t *ent, int i) {
35
+//	return ent[i];
36
+// }
37
+// int64_t getPpKernel() {
38
+//	int64_t pp_kernel = 0;
39
+//	kstat_ctl_t *ksc;
40
+//	kstat_t *ks;
41
+//	kstat_named_t *knp;
42
+//	kid_t kid;
43
+//
44
+//	if ((ksc = kstat_open()) == NULL) {
45
+//		return -1;
46
+//	}
47
+//	if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) {
48
+//		return -1;
49
+//	}
50
+//	if (((kid = kstat_read(ksc, ks, NULL)) == -1) ||
51
+//	    ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) {
52
+//		return -1;
53
+//	}
54
+//	switch (knp->data_type) {
55
+//	case KSTAT_DATA_UINT64:
56
+//		pp_kernel = knp->value.ui64;
57
+//		break;
58
+//	case KSTAT_DATA_UINT32:
59
+//		pp_kernel = knp->value.ui32;
60
+//		break;
61
+//	}
62
+//	pp_kernel *= sysconf(_SC_PAGESIZE);
63
+//	return (pp_kernel > 0 ? pp_kernel : -1);
64
+// }
65
+import "C"
66
+
67
+// Get the system memory info using sysconf same as prtconf
68
+func getTotalMem() int64 {
69
+	pagesize := C.sysconf(C._SC_PAGESIZE)
70
+	npages := C.sysconf(C._SC_PHYS_PAGES)
71
+	return int64(pagesize * npages)
72
+}
73
+
74
+func getFreeMem() int64 {
75
+	pagesize := C.sysconf(C._SC_PAGESIZE)
76
+	npages := C.sysconf(C._SC_AVPHYS_PAGES)
77
+	return int64(pagesize * npages)
78
+}
79
+
80
+// ReadMemInfo retrieves memory statistics of the host system and returns a
81
+//  MemInfo type.
82
+func ReadMemInfo() (*MemInfo, error) {
83
+
84
+	ppKernel := C.getPpKernel()
85
+	MemTotal := getTotalMem()
86
+	MemFree := getFreeMem()
87
+	SwapTotal, SwapFree, err := getSysSwap()
88
+
89
+	if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
90
+		SwapFree < 0 {
91
+		return nil, fmt.Errorf("Error getting system memory info %v\n", err)
92
+	}
93
+
94
+	meminfo := &MemInfo{}
95
+	// Total memory is total physical memory less than memory locked by kernel
96
+	meminfo.MemTotal = MemTotal - int64(ppKernel)
97
+	meminfo.MemFree = MemFree
98
+	meminfo.SwapTotal = SwapTotal
99
+	meminfo.SwapFree = SwapFree
100
+
101
+	return meminfo, nil
102
+}
103
+
104
+func getSysSwap() (int64, int64, error) {
105
+	var tSwap int64
106
+	var fSwap int64
107
+	var diskblksPerPage int64
108
+	num, err := C.swapctl(C.SC_GETNSWP, nil)
109
+	if err != nil {
110
+		return -1, -1, err
111
+	}
112
+	st := C.allocSwaptable(num)
113
+	_, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st))
114
+	if err != nil {
115
+		C.freeSwaptable(st)
116
+		return -1, -1, err
117
+	}
118
+
119
+	diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT)
120
+	for i := 0; i < int(num); i++ {
121
+		swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i))
122
+		tSwap += int64(swapent.ste_pages) * diskblksPerPage
123
+		fSwap += int64(swapent.ste_free) * diskblksPerPage
124
+	}
125
+	C.freeSwaptable(st)
126
+	return tSwap, fSwap, nil
127
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !linux,!windows
1
+// +build !linux,!windows,!solaris
2 2
 
3 3
 package system
4 4
 
... ...
@@ -15,3 +15,20 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
15 15
 		rdev: uint64(s.Rdev),
16 16
 		mtim: s.Mtim}, nil
17 17
 }
18
+
19
+// FromStatT loads a system.StatT from a syscal.Stat_t.
20
+func FromStatT(s *syscall.Stat_t) (*StatT, error) {
21
+	return fromStatT(s)
22
+}
23
+
24
+// Stat takes a path to a file and returns
25
+// a system.StatT type pertaining to that file.
26
+//
27
+// Throws an error if the file does not exist
28
+func Stat(path string) (*StatT, error) {
29
+	s := &syscall.Stat_t{}
30
+	if err := syscall.Stat(path, s); err != nil {
31
+		return nil, err
32
+	}
33
+	return fromStatT(s)
34
+}
18 35
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+package runconfig
1
+
2
+import (
3
+	"fmt"
4
+	"strings"
5
+
6
+	"github.com/docker/engine-api/types/container"
7
+)
8
+
9
+// DefaultDaemonNetworkMode returns the default network stack the daemon should
10
+// use.
11
+func DefaultDaemonNetworkMode() container.NetworkMode {
12
+	return container.NetworkMode("default")
13
+}
14
+
15
+// IsPreDefinedNetwork indicates if a network is predefined by the daemon
16
+func IsPreDefinedNetwork(network string) bool {
17
+	return false
18
+}
19
+
20
+// ValidateNetMode ensures that the various combinations of requested
21
+// network settings are valid.
22
+func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
23
+	// We may not be passed a host config, such as in the case of docker commit
24
+	if hc == nil {
25
+		return nil
26
+	}
27
+	parts := strings.Split(string(hc.NetworkMode), ":")
28
+	switch mode := parts[0]; mode {
29
+	case "default", "none":
30
+	default:
31
+		return fmt.Errorf("invalid --net: %s", hc.NetworkMode)
32
+	}
33
+	return nil
34
+}
35
+
36
+// ValidateIsolation performs platform specific validation of the
37
+// isolation level in the hostconfig structure.
38
+// This setting is currently discarded for Solaris so this is a no-op.
39
+func ValidateIsolation(hc *container.HostConfig) error {
40
+	return nil
41
+}
42
+
43
+// ValidateQoS performs platform specific validation of the QoS settings
44
+// a disk can be limited by either Bps or IOps, but not both.
45
+func ValidateQoS(hc *container.HostConfig) error {
46
+	return nil
47
+}
... ...
@@ -1,4 +1,4 @@
1
-// +build !windows
1
+// +build !windows,!solaris
2 2
 
3 3
 package runconfig
4 4
 
... ...
@@ -1,4 +1,4 @@
1
-// +build linux freebsd
1
+// +build linux freebsd solaris
2 2
 
3 3
 // Package local provides the default implementation for volumes. It
4 4
 // is used to mount data volume containers and directories local to
... ...
@@ -1,4 +1,4 @@
1
-// +build linux freebsd
1
+// +build linux freebsd solaris
2 2
 
3 3
 package store
4 4