Get the Docker Engine to build clean on Solaris
Signed-off-by: Amit Krishnan <krish.amit@gmail.com>
This commit is contained in:
parent
91bc4cca58
commit
86d8758e2b
60 changed files with 1380 additions and 43 deletions
74
cmd/dockerd/daemon_solaris.go
Normal file
74
cmd/dockerd/daemon_solaris.go
Normal file
|
@ -0,0 +1,74 @@
|
|||
// +build solaris
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
)
|
||||
|
||||
const defaultDaemonConfigFile = ""
|
||||
|
||||
// currentUserIsOwner checks whether the current user is the owner of the given
|
||||
// file.
|
||||
func currentUserIsOwner(f string) bool {
|
||||
if fileInfo, err := system.Stat(f); err == nil && fileInfo != nil {
|
||||
if int(fileInfo.UID()) == os.Getuid() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// setDefaultUmask sets the umask to 0022 to avoid problems
|
||||
// caused by custom umask
|
||||
func setDefaultUmask() error {
|
||||
desiredUmask := 0022
|
||||
syscall.Umask(desiredUmask)
|
||||
if umask := syscall.Umask(desiredUmask); umask != desiredUmask {
|
||||
return fmt.Errorf("failed to set umask: expected %#o, got %#o", desiredUmask, umask)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDaemonConfDir() string {
|
||||
return "/etc/docker"
|
||||
}
|
||||
|
||||
// setupConfigReloadTrap configures the USR2 signal to reload the configuration.
|
||||
func (cli *DaemonCli) setupConfigReloadTrap() {
|
||||
}
|
||||
|
||||
// notifySystem sends a message to the host when the server is ready to be used
|
||||
func notifySystem() {
|
||||
}
|
||||
|
||||
func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption {
|
||||
opts := []libcontainerd.RemoteOption{}
|
||||
return opts
|
||||
}
|
||||
|
||||
// getLibcontainerdRoot gets the root directory for libcontainerd/containerd to
|
||||
// store their state.
|
||||
func (cli *DaemonCli) getLibcontainerdRoot() string {
|
||||
return filepath.Join(cli.Config.ExecRoot, "libcontainerd")
|
||||
}
|
||||
|
||||
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 +1,4 @@
|
|||
// +build !windows
|
||||
// +build !windows,!solaris
|
||||
|
||||
package main
|
||||
|
||||
|
|
95
container/container_solaris.go
Normal file
95
container/container_solaris.go
Normal file
|
@ -0,0 +1,95 @@
|
|||
// +build solaris
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/engine-api/types/container"
|
||||
)
|
||||
|
||||
// Container holds fields specific to the Solaris implementation. See
|
||||
// CommonContainer for standard fields common to all containers.
|
||||
type Container struct {
|
||||
CommonContainer
|
||||
|
||||
// fields below here are platform specific.
|
||||
HostnamePath string
|
||||
HostsPath string
|
||||
ResolvConfPath string
|
||||
}
|
||||
|
||||
// ExitStatus provides exit reasons for a container.
|
||||
type ExitStatus struct {
|
||||
// The exit code with which the container exited.
|
||||
ExitCode int
|
||||
}
|
||||
|
||||
// CreateDaemonEnvironment creates a new environment variable slice for this container.
|
||||
func (container *Container) CreateDaemonEnvironment(linkedEnv []string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
|
||||
return volumeMounts, nil
|
||||
}
|
||||
|
||||
// TrySetNetworkMount attempts to set the network mounts given a provided destination and
|
||||
// the path to use for it; return true if the given destination was a network mount file
|
||||
func (container *Container) TrySetNetworkMount(destination string, path string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// NetworkMounts returns the list of network mounts.
|
||||
func (container *Container) NetworkMounts() []Mount {
|
||||
var mount []Mount
|
||||
return mount
|
||||
}
|
||||
|
||||
// CopyImagePathContent copies files in destination to the volume.
|
||||
func (container *Container) CopyImagePathContent(v volume.Volume, destination string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmountIpcMounts unmount Ipc related mounts.
|
||||
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
|
||||
}
|
||||
|
||||
// IpcMounts returns the list of Ipc related mounts.
|
||||
func (container *Container) IpcMounts() []Mount {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateContainer updates configuration of a container
|
||||
func (container *Container) UpdateContainer(hostConfig *container.HostConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmountVolumes explicitly unmounts volumes from the container.
|
||||
func (container *Container) UnmountVolumes(forceSyscall bool, volumeEventLog func(name, action string, attributes map[string]string)) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TmpfsMounts returns the list of tmpfs mounts
|
||||
func (container *Container) TmpfsMounts() []Mount {
|
||||
var mounts []Mount
|
||||
return mounts
|
||||
}
|
||||
|
||||
// cleanResourcePath cleans a resource path and prepares to combine with mnt path
|
||||
func cleanResourcePath(path string) string {
|
||||
return filepath.Join(string(os.PathSeparator), path)
|
||||
}
|
||||
|
||||
// BuildHostnameFile writes the container's hostname file.
|
||||
func (container *Container) BuildHostnameFile() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// canMountFS determines if the file system for the container
|
||||
// can be mounted locally. A no-op on non-Windows platforms
|
||||
func (container *Container) canMountFS() bool {
|
||||
return true
|
||||
}
|
7
container/state_solaris.go
Normal file
7
container/state_solaris.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package container
|
||||
|
||||
// setFromExitStatus is a platform specific helper function to set the state
|
||||
// based on the ExitStatus structure.
|
||||
func (s *State) setFromExitStatus(exitStatus *ExitStatus) {
|
||||
s.ExitCode = exitStatus.ExitCode
|
||||
}
|
39
daemon/config_solaris.go
Normal file
39
daemon/config_solaris.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultPidFile = "/var/run/docker.pid"
|
||||
defaultGraph = "/var/lib/docker"
|
||||
defaultExec = "zones"
|
||||
)
|
||||
|
||||
// Config defines the configuration of a docker daemon.
|
||||
// These are the configuration settings that you pass
|
||||
// to the docker daemon when you launch it with say: `docker -d -e lxc`
|
||||
type Config struct {
|
||||
CommonConfig
|
||||
|
||||
// Fields below here are platform specific.
|
||||
ExecRoot string `json:"exec-root,omitempty"`
|
||||
}
|
||||
|
||||
// bridgeConfig stores all the bridge driver specific
|
||||
// configuration.
|
||||
type bridgeConfig struct {
|
||||
commonBridgeConfig
|
||||
}
|
||||
|
||||
// InstallFlags adds command-line options to the top-level flag parser for
|
||||
// the current process.
|
||||
// Subsequent calls to `flag.Parse` will populate config with values parsed
|
||||
// from the command-line.
|
||||
func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) {
|
||||
// First handle install flags which are consistent cross-platform
|
||||
config.InstallCommonFlags(cmd, usageFn)
|
||||
|
||||
// Then platform-specific install flags
|
||||
config.attachExperimentalFlags(cmd, usageFn)
|
||||
}
|
50
daemon/container_operations_solaris.go
Normal file
50
daemon/container_operations_solaris.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
// +build solaris
|
||||
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/container"
|
||||
networktypes "github.com/docker/engine-api/types/network"
|
||||
"github.com/docker/libnetwork"
|
||||
)
|
||||
|
||||
func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ConnectToNetwork connects a container to a network
|
||||
func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error {
|
||||
return fmt.Errorf("Solaris does not support connecting a running container to a network")
|
||||
}
|
||||
|
||||
// getSize returns real size & virtual size
|
||||
func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// DisconnectFromNetwork disconnects a container from the network
|
||||
func (daemon *Daemon) DisconnectFromNetwork(container *container.Container, n libnetwork.Network, force bool) error {
|
||||
return fmt.Errorf("Solaris does not support disconnecting a running container from a network")
|
||||
}
|
||||
|
||||
func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) mountVolumes(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 {
|
||||
return false
|
||||
}
|
|
@ -799,7 +799,7 @@ func NewDaemon(config *Config, registryService *registry.Service, containerdRemo
|
|||
sysInfo := sysinfo.New(false)
|
||||
// Check if Devices cgroup is mounted, it is hard requirement for container security,
|
||||
// on Linux/FreeBSD.
|
||||
if runtime.GOOS != "windows" && !sysInfo.CgroupDevicesEnabled {
|
||||
if runtime.GOOS != "windows" && runtime.GOOS != "solaris" && !sysInfo.CgroupDevicesEnabled {
|
||||
return nil, fmt.Errorf("Devices cgroup isn't mounted")
|
||||
}
|
||||
|
||||
|
|
159
daemon/daemon_solaris.go
Normal file
159
daemon/daemon_solaris.go
Normal file
|
@ -0,0 +1,159 @@
|
|||
// +build solaris,cgo
|
||||
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/parsers/kernel"
|
||||
"github.com/docker/docker/reference"
|
||||
"github.com/docker/engine-api/types"
|
||||
containertypes "github.com/docker/engine-api/types/container"
|
||||
"github.com/docker/libnetwork"
|
||||
nwconfig "github.com/docker/libnetwork/config"
|
||||
)
|
||||
|
||||
//#include <zone.h>
|
||||
import "C"
|
||||
|
||||
const (
|
||||
defaultVirtualSwitch = "Virtual Switch"
|
||||
platformSupported = true
|
||||
solarisMinCPUShares = 1
|
||||
solarisMaxCPUShares = 65535
|
||||
)
|
||||
|
||||
func (daemon *Daemon) cleanupMountsByID(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// setupInitLayer 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 setupInitLayer(initLayer string, rootUID, rootGID int) 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 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
warnings := []string{}
|
||||
return warnings, nil
|
||||
}
|
||||
|
||||
// verifyDaemonSettings performs validation of daemon config struct
|
||||
func verifyDaemonSettings(config *Config) error {
|
||||
// checkSystem validates platform-specific requirements
|
||||
return nil
|
||||
}
|
||||
|
||||
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) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// configureKernelSecuritySupport configures and validate security support for the kernel
|
||||
func configureKernelSecuritySupport(config *Config, driverName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) {
|
||||
return nil, 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 nil
|
||||
}
|
||||
|
||||
// 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 restoreCustomImage(is image.Store, ls layer.Store, rs reference.Store) error {
|
||||
// Solaris has no custom images to register
|
||||
return nil
|
||||
}
|
||||
|
||||
func driverOptions(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{}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !linux,!freebsd,!windows
|
||||
// +build !linux,!freebsd,!windows,!solaris
|
||||
|
||||
package daemon
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build !linux,!darwin,!freebsd,!windows
|
||||
// +build !linux,!darwin,!freebsd,!windows,!solaris
|
||||
|
||||
package daemon
|
||||
|
||||
|
|
11
daemon/exec_solaris.go
Normal file
11
daemon/exec_solaris.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/daemon/exec"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
)
|
||||
|
||||
func execSetPlatformOpt(c *container.Container, ec *exec.Config, p *libcontainerd.Process) error {
|
||||
return nil
|
||||
}
|
65
daemon/graphdriver/driver_solaris.go
Normal file
65
daemon/graphdriver/driver_solaris.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
// +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"
|
||||
|
||||
log "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
|
||||
}
|
||||
|
||||
// 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))
|
||||
buf := C.getstatfs(cs)
|
||||
|
||||
// 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) {
|
||||
log.Debugf("[zfs] no zfs dataset found for rootdir '%s'", mountPath)
|
||||
C.free(unsafe.Pointer(buf))
|
||||
return false, ErrPrerequisites
|
||||
}
|
||||
|
||||
C.free(unsafe.Pointer(buf))
|
||||
C.free(unsafe.Pointer(cs))
|
||||
return true, nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !linux,!windows,!freebsd
|
||||
// +build !linux,!windows,!freebsd,!solaris
|
||||
|
||||
package graphdriver
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build !exclude_graphdriver_zfs,linux !exclude_graphdriver_zfs,freebsd
|
||||
// +build !exclude_graphdriver_zfs,linux !exclude_graphdriver_zfs,freebsd, solaris
|
||||
|
||||
package register
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build linux freebsd
|
||||
// +build linux freebsd solaris
|
||||
|
||||
package zfs
|
||||
|
||||
|
|
59
daemon/graphdriver/zfs/zfs_solaris.go
Normal file
59
daemon/graphdriver/zfs/zfs_solaris.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
// +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"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/daemon/graphdriver"
|
||||
)
|
||||
|
||||
func checkRootdirFs(rootdir string) error {
|
||||
|
||||
cs := C.CString(filepath.Dir(rootdir))
|
||||
buf := C.getstatfs(cs)
|
||||
|
||||
// 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) {
|
||||
log.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
|
||||
C.free(unsafe.Pointer(buf))
|
||||
return graphdriver.ErrPrerequisites
|
||||
}
|
||||
|
||||
C.free(unsafe.Pointer(buf))
|
||||
C.free(unsafe.Pointer(cs))
|
||||
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,4 +1,4 @@
|
|||
// +build !linux,!freebsd
|
||||
// +build !linux,!freebsd,!solaris
|
||||
|
||||
package zfs
|
||||
|
||||
|
|
40
daemon/inspect_solaris.go
Normal file
40
daemon/inspect_solaris.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/daemon/exec"
|
||||
"github.com/docker/engine-api/types"
|
||||
)
|
||||
|
||||
// This sets platform-specific fields
|
||||
func setPlatformSpecificContainerFields(container *container.Container, contJSONBase *types.ContainerJSONBase) *types.ContainerJSONBase {
|
||||
return contJSONBase
|
||||
}
|
||||
|
||||
// containerInspectPre120 get containers for pre 1.20 APIs.
|
||||
func (daemon *Daemon) containerInspectPre120(name string) (*types.ContainerJSON, error) {
|
||||
return daemon.containerInspectCurrent(name, false)
|
||||
}
|
||||
|
||||
func addMountPoints(container *container.Container) []types.MountPoint {
|
||||
mountPoints := make([]types.MountPoint, 0, len(container.MountPoints))
|
||||
for _, m := range container.MountPoints {
|
||||
mountPoints = append(mountPoints, types.MountPoint{
|
||||
Name: m.Name,
|
||||
Source: m.Path(),
|
||||
Destination: m.Destination,
|
||||
Driver: m.Driver,
|
||||
RW: m.RW,
|
||||
})
|
||||
}
|
||||
return mountPoints
|
||||
}
|
||||
|
||||
func inspectExecProcessConfig(e *exec.Config) *backend.ExecProcessConfig {
|
||||
return &backend.ExecProcessConfig{
|
||||
Tty: e.Tty,
|
||||
Entrypoint: e.Entrypoint,
|
||||
Arguments: e.Args,
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !windows
|
||||
// +build !windows,!solaris
|
||||
|
||||
package daemon
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build linux freebsd
|
||||
// +build linux freebsd solaris
|
||||
|
||||
package daemon
|
||||
|
||||
|
|
18
daemon/monitor_solaris.go
Normal file
18
daemon/monitor_solaris.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
)
|
||||
|
||||
// platformConstructExitStatus returns a platform specific exit status structure
|
||||
func platformConstructExitStatus(e libcontainerd.StateInfo) *container.ExitStatus {
|
||||
return &container.ExitStatus{
|
||||
ExitCode: int(e.ExitCode),
|
||||
}
|
||||
}
|
||||
|
||||
// postRunProcessing perfoms any processing needed on the container after it has stopped.
|
||||
func (daemon *Daemon) postRunProcessing(container *container.Container, e libcontainerd.StateInfo) error {
|
||||
return nil
|
||||
}
|
12
daemon/oci_solaris.go
Normal file
12
daemon/oci_solaris.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
"github.com/docker/docker/oci"
|
||||
)
|
||||
|
||||
func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, error) {
|
||||
s := oci.DefaultSpec()
|
||||
return (*libcontainerd.Spec)(&s), nil
|
||||
}
|
34
daemon/stats_collector_solaris.go
Normal file
34
daemon/stats_collector_solaris.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/container"
|
||||
"time"
|
||||
)
|
||||
|
||||
// newStatsCollector returns a new statsCollector for collection stats
|
||||
// for a registered container at the specified interval. The collector allows
|
||||
// non-running containers to be added and will start processing stats when
|
||||
// they are started.
|
||||
func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector {
|
||||
return &statsCollector{}
|
||||
}
|
||||
|
||||
// statsCollector manages and provides container resource stats
|
||||
type statsCollector struct {
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (s *statsCollector) collect(c *container.Container) chan interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// stopCollection closes the channels for all subscribers and removes
|
||||
// the container from metrics collection.
|
||||
func (s *statsCollector) stopCollection(c *container.Container) {
|
||||
}
|
||||
|
||||
// unsubscribe removes a specific subscriber from receiving updates for a container's stats.
|
||||
func (s *statsCollector) unsubscribe(c *container.Container, ch chan interface{}) {
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !windows
|
||||
// +build !windows,!solaris
|
||||
|
||||
package daemon
|
||||
|
||||
|
|
11
daemon/update_solaris.go
Normal file
11
daemon/update_solaris.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
"github.com/docker/engine-api/types/container"
|
||||
)
|
||||
|
||||
func toContainerdResources(resources container.Resources) libcontainerd.Resources {
|
||||
var r libcontainerd.Resources
|
||||
return r
|
||||
}
|
|
@ -93,7 +93,7 @@ if command -v git &> /dev/null && [ -d .git ] && git rev-parse &> /dev/null; the
|
|||
git status --porcelain --untracked-files=no
|
||||
echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
fi
|
||||
! BUILDTIME=$(date --rfc-3339 ns | sed -e 's/ /T/') &> /dev/null
|
||||
! BUILDTIME=$(date --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/') &> /dev/null
|
||||
if [ -z $BUILDTIME ]; then
|
||||
# If using bash 3.1 which doesn't support --rfc-3389, eg Windows CI
|
||||
BUILDTIME=$(date -u)
|
||||
|
@ -113,6 +113,12 @@ if [ "$AUTO_GOPATH" ]; then
|
|||
mkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"
|
||||
ln -sf ../../../.. .gopath/src/"${DOCKER_PKG}"
|
||||
export GOPATH="${PWD}/.gopath:${PWD}/vendor"
|
||||
|
||||
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 GOPATH="${GOPATH}:/usr/lib/gocode/1.5"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! "$GOPATH" ]; then
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build linux freebsd darwin openbsd
|
||||
// +build linux freebsd darwin openbsd solaris
|
||||
|
||||
package layer
|
||||
|
||||
|
|
56
libcontainerd/client_solaris.go
Normal file
56
libcontainerd/client_solaris.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package libcontainerd
|
||||
|
||||
type client struct {
|
||||
clientCommon
|
||||
|
||||
// Platform specific properties below here.
|
||||
}
|
||||
|
||||
func (clnt *client) AddProcess(containerID, processFriendlyName string, specp Process) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clnt *client) Create(containerID string, spec Spec, options ...CreateOption) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clnt *client) Signal(containerID string, sig int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clnt *client) Resize(containerID, processFriendlyName string, width, height int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clnt *client) Pause(containerID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clnt *client) Resume(containerID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clnt *client) Stats(containerID string) (*Stats, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Restore is the handler for restoring a container
|
||||
func (clnt *client) Restore(containerID string, unusedOnWindows ...CreateOption) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clnt *client) GetPidsForContainer(containerID string) ([]int, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Summary returns a summary of the processes running in a container.
|
||||
func (clnt *client) Summary(containerID string) ([]Summary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// UpdateResources updates resources for a running container.
|
||||
func (clnt *client) UpdateResources(containerID string, resources Resources) error {
|
||||
// Updating resource isn't supported on Solaris
|
||||
// but we should return nil for enabling updating container
|
||||
return nil
|
||||
}
|
5
libcontainerd/container_solaris.go
Normal file
5
libcontainerd/container_solaris.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package libcontainerd
|
||||
|
||||
type container struct {
|
||||
containerCommon
|
||||
}
|
6
libcontainerd/process_solaris.go
Normal file
6
libcontainerd/process_solaris.go
Normal file
|
@ -0,0 +1,6 @@
|
|||
package libcontainerd
|
||||
|
||||
// process keeps the state for both main container process and exec process.
|
||||
type process struct {
|
||||
processCommon
|
||||
}
|
25
libcontainerd/remote_solaris.go
Normal file
25
libcontainerd/remote_solaris.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package libcontainerd
|
||||
|
||||
import "github.com/docker/docker/pkg/locker"
|
||||
|
||||
type remote struct {
|
||||
}
|
||||
|
||||
func (r *remote) Client(b Backend) (Client, error) {
|
||||
c := &client{
|
||||
clientCommon: clientCommon{
|
||||
backend: b,
|
||||
containers: make(map[string]*container),
|
||||
locker: locker.New(),
|
||||
},
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (r *remote) Cleanup() {
|
||||
}
|
||||
|
||||
// New creates a fresh instance of libcontainerd remote.
|
||||
func New(_ string, _ ...RemoteOption) (Remote, error) {
|
||||
return &remote{}, nil
|
||||
}
|
38
libcontainerd/types_solaris.go
Normal file
38
libcontainerd/types_solaris.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package libcontainerd
|
||||
|
||||
import (
|
||||
"github.com/opencontainers/specs/specs-go"
|
||||
)
|
||||
|
||||
// Spec is the base configuration for the container. It specifies platform
|
||||
// independent configuration. This information must be included when the
|
||||
// bundle is packaged for distribution.
|
||||
type Spec specs.Spec
|
||||
|
||||
// Process contains information to start a specific application inside the container.
|
||||
type Process struct {
|
||||
// Terminal creates an interactive terminal for the container.
|
||||
Terminal bool `json:"terminal"`
|
||||
// Args specifies the binary and arguments for the application to execute.
|
||||
Args []string `json:"args"`
|
||||
}
|
||||
|
||||
// Stats contains a stats properties from containerd.
|
||||
type Stats struct{}
|
||||
|
||||
// Summary container a container summary from containerd
|
||||
type Summary struct{}
|
||||
|
||||
// StateInfo contains description about the new state container has entered.
|
||||
type StateInfo struct {
|
||||
CommonStateInfo
|
||||
|
||||
// Platform specific StateInfo
|
||||
}
|
||||
|
||||
// User specifies Solaris specific user and group information for the container's
|
||||
// main process.
|
||||
type User specs.User
|
||||
|
||||
// Resources defines updatable container resource values.
|
||||
type Resources struct{}
|
11
oci/defaults_solaris.go
Normal file
11
oci/defaults_solaris.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package oci
|
||||
|
||||
import (
|
||||
"github.com/opencontainers/specs/specs-go"
|
||||
)
|
||||
|
||||
// DefaultSpec returns default oci spec used by docker.
|
||||
func DefaultSpec() specs.Spec {
|
||||
s := specs.Spec{}
|
||||
return s
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build linux freebsd
|
||||
// +build linux freebsd solaris
|
||||
|
||||
package directory
|
||||
|
||||
|
|
7
pkg/fileutils/fileutils_solaris.go
Normal file
7
pkg/fileutils/fileutils_solaris.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
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
|
||||
}
|
31
pkg/listeners/listeners_solaris.go
Normal file
31
pkg/listeners/listeners_solaris.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package listeners
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/docker/go-connections/sockets"
|
||||
)
|
||||
|
||||
// Init creates new listeners for the server.
|
||||
func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) (ls []net.Listener, err error) {
|
||||
switch proto {
|
||||
case "tcp":
|
||||
l, err := sockets.NewTCPSocket(addr, tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ls = append(ls, l)
|
||||
case "unix":
|
||||
l, err := sockets.NewUnixSocket(addr, socketGroup)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't create unix socket %s: %v", addr, err)
|
||||
}
|
||||
ls = append(ls, l)
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid protocol format: %q", proto)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !windows
|
||||
// +build !windows,!solaris
|
||||
|
||||
package listeners
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build !linux,!freebsd freebsd,!cgo
|
||||
// +build !linux,!freebsd freebsd,!cgo solaris,!cgo
|
||||
|
||||
package mount
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ func GetMounts() ([]*Info, error) {
|
|||
return parseMountTable()
|
||||
}
|
||||
|
||||
// Mounted looks at /proc/self/mountinfo to determine of the specified
|
||||
// mountpoint has been mounted
|
||||
// Mounted determines if a specified mountpoint has been mounted.
|
||||
// On Linux it looks at /proc/self/mountinfo and on Solaris at mnttab.
|
||||
func Mounted(mountpoint string) (bool, error) {
|
||||
entries, err := parseMountTable()
|
||||
if err != nil {
|
||||
|
|
33
pkg/mount/mounter_solaris.go
Normal file
33
pkg/mount/mounter_solaris.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
// +build solaris,cgo
|
||||
|
||||
package mount
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #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,4 +1,4 @@
|
|||
// +build !linux,!freebsd freebsd,!cgo
|
||||
// +build !linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
|
||||
|
||||
package mount
|
||||
|
||||
|
|
37
pkg/mount/mountinfo_solaris.go
Normal file
37
pkg/mount/mountinfo_solaris.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
// +build solaris,cgo
|
||||
|
||||
package mount
|
||||
|
||||
/*
|
||||
#include <stdio.h>
|
||||
#include <sys/mnttab.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func parseMountTable() ([]*Info, error) {
|
||||
mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r"))
|
||||
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,4 +1,4 @@
|
|||
// +build !windows,!linux,!freebsd freebsd,!cgo
|
||||
// +build !windows,!linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
|
||||
|
||||
package mount
|
||||
|
||||
|
|
14
pkg/parsers/kernel/uname_solaris.go
Normal file
14
pkg/parsers/kernel/uname_solaris.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package kernel
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func uname() (*unix.Utsname, error) {
|
||||
uts := &unix.Utsname{}
|
||||
|
||||
if err := unix.Uname(uts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uts, nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !linux
|
||||
// +build !linux,!solaris
|
||||
|
||||
package kernel
|
||||
|
||||
|
|
37
pkg/parsers/operatingsystem/operatingsystem_solaris.go
Normal file
37
pkg/parsers/operatingsystem/operatingsystem_solaris.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
// +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,15 +0,0 @@
|
|||
package platform
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// runtimeArchitecture gets the name of the current architecture (x86, x86_64, …)
|
||||
func runtimeArchitecture() (string, error) {
|
||||
cmd := exec.Command("uname", "-m")
|
||||
machine, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(machine), nil
|
||||
}
|
18
pkg/platform/architecture_unix.go
Normal file
18
pkg/platform/architecture_unix.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
// +build freebsd solaris
|
||||
|
||||
package platform
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// runtimeArchitecture get the name of the current architecture (i86pc, sun4v)
|
||||
func runtimeArchitecture() (string, error) {
|
||||
cmd := exec.Command("/usr/bin/uname", "-m")
|
||||
machine, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(machine)), nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build freebsd
|
||||
// +build freebsd solaris
|
||||
|
||||
package reexec
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// +build !linux,!windows,!freebsd
|
||||
// +build !linux,!windows,!freebsd,!solaris
|
||||
|
||||
package reexec
|
||||
|
||||
|
|
42
pkg/signal/signal_solaris.go
Normal file
42
pkg/signal/signal_solaris.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
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,4 +1,4 @@
|
|||
// +build !linux,!darwin,!freebsd,!windows
|
||||
// +build !linux,!darwin,!freebsd,!windows,!solaris
|
||||
|
||||
package signal
|
||||
|
||||
|
|
119
pkg/sysinfo/sysinfo_solaris.go
Normal file
119
pkg/sysinfo/sysinfo_solaris.go
Normal file
|
@ -0,0 +1,119 @@
|
|||
// +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,
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
128
pkg/system/meminfo_solaris.go
Normal file
128
pkg/system/meminfo_solaris.go
Normal file
|
@ -0,0 +1,128 @@
|
|||
// +build solaris,cgo
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #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,4 +1,4 @@
|
|||
// +build !linux,!windows
|
||||
// +build !linux,!windows,!solaris
|
||||
|
||||
package system
|
||||
|
||||
|
|
|
@ -15,3 +15,20 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
|||
rdev: uint64(s.Rdev),
|
||||
mtim: s.Mtim}, nil
|
||||
}
|
||||
|
||||
// FromStatT loads a system.StatT from a syscal.Stat_t.
|
||||
func FromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
||||
// Stat takes a path to a file and returns
|
||||
// a system.StatT type pertaining to that file.
|
||||
//
|
||||
// Throws an error if the file does not exist
|
||||
func Stat(path string) (*StatT, error) {
|
||||
s := &syscall.Stat_t{}
|
||||
if err := syscall.Stat(path, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fromStatT(s)
|
||||
}
|
||||
|
|
48
runconfig/hostconfig_solaris.go
Normal file
48
runconfig/hostconfig_solaris.go
Normal file
|
@ -0,0 +1,48 @@
|
|||
package runconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/engine-api/types/container"
|
||||
)
|
||||
|
||||
// DefaultDaemonNetworkMode returns the default network stack the daemon should
|
||||
// use.
|
||||
func DefaultDaemonNetworkMode() container.NetworkMode {
|
||||
return container.NetworkMode("default")
|
||||
}
|
||||
|
||||
// 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
|
||||
if hc == nil {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(string(hc.NetworkMode), ":")
|
||||
switch mode := parts[0]; mode {
|
||||
case "default", "none":
|
||||
default:
|
||||
return fmt.Errorf("invalid --net: %s", hc.NetworkMode)
|
||||
}
|
||||
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
|
||||
// a disk can be limited by either Bps or IOps, but not both.
|
||||
func ValidateQoS(hc *container.HostConfig) error {
|
||||
return nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !windows
|
||||
// +build !windows,!solaris
|
||||
|
||||
package runconfig
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build linux freebsd
|
||||
// +build linux freebsd solaris
|
||||
|
||||
// Package local provides the default implementation for volumes. It
|
||||
// is used to mount data volume containers and directories local to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build linux freebsd
|
||||
// +build linux freebsd solaris
|
||||
|
||||
package store
|
||||
|
||||
|
|
Loading…
Reference in a new issue