Add solaris build support

Signed-off-by: Edward Pilatowicz <edward.pilatowicz@oracle.com>
This commit is contained in:
Edward Pilatowicz 2017-06-28 10:50:04 -07:00
parent 534a137ed3
commit 56c1f5c184
21 changed files with 225 additions and 32 deletions

View File

@ -31,6 +31,7 @@ env:
- TRAVIS_GOOS=windows TRAVIS_CGO_ENABLED=1
- TRAVIS_GOOS=linux TRAVIS_CGO_ENABLED=1
- TRAVIS_GOOS=darwin TRAVIS_CGO_ENABLED=0
- TRAVIS_GOOS=solaris TRAVIS_CGO_ENABLED=0
before_install:
- uname -r

View File

@ -10,8 +10,10 @@ REVISION=$(shell git rev-parse HEAD)$(shell if ! git diff --no-ext-diff --quiet
ifneq "$(strip $(shell command -v go 2>/dev/null))" ""
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
else
GOOS ?= $$GOOS
GOARCH ?= $$GOARCH
endif
WHALE = "🇩"
@ -22,16 +24,28 @@ ifeq ("$(OS)", "Windows_NT")
ONI="-"
FIX_PATH = $(subst /,\,$1)
endif
GOARCH ?= $(shell go env GOARCH)
RELEASE=containerd-$(VERSION:v%=%).${GOOS}-${GOARCH}
PKG=github.com/containerd/containerd
# on SunOS default to gnu utilities for things like grep, sed, etc.
ifeq ($(shell uname -s),SunOS)
export PATH := /usr/gnu/bin:$(PATH)
endif
# Project packages.
PACKAGES=$(shell go list ./... | grep -v /vendor/)
INTEGRATION_PACKAGE=${PKG}
TEST_REQUIRES_ROOT_PACKAGES=$(shell for f in $$(git grep -l testutil.RequiresRoot | grep -v Makefile);do echo "${PKG}/$$(dirname $$f)"; done)
TEST_REQUIRES_ROOT_PACKAGES=$(filter \
${PACKAGES}, \
$(shell \
for f in $$(git grep -l testutil.RequiresRoot | grep -v Makefile); do \
d="$$(dirname $$f)"; \
[ "$$d" = "." ] && echo "${PKG}" && continue; \
echo "${PKG}/$$d"; \
done | sort -u) \
)
# Project binaries.
COMMANDS=ctr containerd
@ -46,8 +60,16 @@ endif
GO_TAGS=$(if $(BUILDTAGS),-tags "$(BUILDTAGS)",)
GO_LDFLAGS=-ldflags "-X $(PKG)/version.Version=$(VERSION) -X $(PKG)/version.Revision=$(REVISION) -X $(PKG)/version.Package=$(PKG) $(EXTRA_LDFLAGS)"
# go test -race is only supported on the patforms listed below.
TESTFLAGS_RACE=
ifeq ($(filter \
linux/amd64 freebsd/amd64 darwin/amd64 windows/amd64, \
$(GOOS)/$(GOARCH)),$(GOOS)/$(GOARCH))
TESTFLAGS_RACE= -race
endif
# Flags passed to `go test`
TESTFLAGS ?=-parallel 8 -race -v
TESTFLAGS ?=-parallel 8 -v $(TESTFLAGS_RACE)
.PHONY: clean all AUTHORS fmt vet lint dco build binaries test integration setup generate protos checkprotos coverage ci check help install uninstall vendor release
.DEFAULT: default

View File

@ -1,4 +1,4 @@
// +build linux freebsd
// +build linux freebsd solaris
package archive

View File

@ -1,4 +1,4 @@
// +build darwin freebsd
// +build darwin freebsd solaris
package main

View File

@ -0,0 +1,18 @@
// +build solaris
package main
import "github.com/containerd/containerd/server"
func defaultConfig() *server.Config {
return &server.Config{
Root: "/var/lib/containerd",
GRPC: server.GRPCConfig{
Address: server.DefaultAddress,
},
Debug: server.Debug{
Level: "info",
Address: server.DefaultDebugAddress,
},
}
}

View File

@ -1,4 +1,4 @@
// +build !linux,!windows
// +build !linux,!windows,!solaris
package main

View File

@ -1,4 +1,4 @@
// +build darwin freebsd
// +build darwin freebsd solaris
package main

View File

@ -1,4 +1,4 @@
// +build darwin freebsd
// +build darwin freebsd solaris
package main

View File

@ -1,15 +0,0 @@
package local
import (
"os"
"syscall"
"time"
)
func getStartTime(fi os.FileInfo) time.Time {
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
return time.Unix(int64(st.Ctim.Sec), int64(st.Ctim.Nsec))
}
return fi.ModTime()
}

View File

@ -1,4 +1,4 @@
// +build darwin freebsd
// +build linux solaris darwin freebsd
package local
@ -6,11 +6,14 @@ import (
"os"
"syscall"
"time"
"github.com/containerd/containerd/sys"
)
func getStartTime(fi os.FileInfo) time.Time {
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
return time.Unix(int64(st.Ctimespec.Sec), int64(st.Ctimespec.Nsec))
return time.Unix(int64(sys.StatCtime(st).Sec),
int64(sys.StatCtime(st).Nsec))
}
return fi.ModTime()

View File

@ -5,6 +5,7 @@ import (
"os"
"syscall"
"github.com/containerd/containerd/sys"
"github.com/containerd/continuity/sysx"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
@ -22,7 +23,7 @@ func copyFileInfo(fi os.FileInfo, name string) error {
}
}
timespec := []unix.Timespec{unix.Timespec(st.Atim), unix.Timespec(st.Mtim)}
timespec := []unix.Timespec{unix.Timespec(sys.StatAtime(st)), unix.Timespec(sys.StatMtime(st))}
if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil {
return errors.Wrapf(err, "failed to utime %s", name)
}

View File

@ -1,4 +1,4 @@
// +build darwin freebsd
// +build solaris darwin freebsd
package fs
@ -7,6 +7,7 @@ import (
"os"
"syscall"
"github.com/containerd/containerd/sys"
"github.com/containerd/continuity/sysx"
"github.com/pkg/errors"
)
@ -23,7 +24,8 @@ func copyFileInfo(fi os.FileInfo, name string) error {
}
}
if err := syscall.UtimesNano(name, []syscall.Timespec{st.Atimespec, st.Mtimespec}); err != nil {
timespec := []syscall.Timespec{sys.StatAtime(st), sys.StatMtime(st)}
if err := syscall.UtimesNano(name, timespec); err != nil {
return errors.Wrapf(err, "failed to utime %s", name)
}

26
fs/dtype_test.go Normal file
View File

@ -0,0 +1,26 @@
package fs
import (
"testing"
"github.com/containerd/containerd/testutil"
)
func TestRequiresRootNOP(t *testing.T) {
// This is a dummy test case that exist to call
// testutil.RequiresRoot() on non-linux platforms. This is
// needed because the Makfile root-coverage tests target
// determines which packages contain root test by grepping for
// testutil.RequiresRoot. Within the fs package, the only test
// that references this symbol is in dtype_linux_test.go, but
// that file is only built on linux. Since the Makefile is not
// go build tag aware it sees this file and then tries to run
// the following command on all platforms: "go test ...
// github.com/containerd/containerd/fs -test.root". On
// non-linux platforms this fails because there are no tests in
// the "fs" package that reference testutil.RequiresRoot. To
// fix this problem we'll add a reference to this symbol below.
testutil.RequiresRoot(t)
}

83
mount/mount_solaris.go Normal file
View File

@ -0,0 +1,83 @@
package mount
// On Solaris we can't invoke the mount system call directly. First,
// the mount system call takes more than 6 arguments, and go doesn't
// support invoking system calls that take more than 6 arguments. Past
// that, the mount system call is a private interfaces. For example,
// the arguments and data structures passed to the kernel to create an
// nfs mount are private and can change at any time. The only public
// and stable interface for creating mounts on Solaris is the mount.8
// command, so we'll invoke that here.
import (
"bytes"
"errors"
"fmt"
"os/exec"
"strings"
"golang.org/x/sys/unix"
)
const (
mountCmd = "/usr/sbin/mount"
)
func doMount(arg ...string) error {
cmd := exec.Command(mountCmd, arg...)
/* Setup Stdin, Stdout, and Stderr */
stderr := new(bytes.Buffer)
cmd.Stdin = nil
cmd.Stdout = nil
cmd.Stderr = stderr
/*
* Run the command. If the command fails create a new error
* object to return that includes stderr output.
*/
err := cmd.Start()
if err != nil {
return err
}
err = cmd.Wait()
if err != nil {
return errors.New(fmt.Sprintf("%v: %s", err, stderr.String()))
}
return nil
}
func (m *Mount) Mount(target string) error {
var err error
if len(m.Options) == 0 {
err = doMount("-F", m.Type, m.Source, target)
} else {
err = doMount("-F", m.Type, "-o", strings.Join(m.Options, ","),
m.Source, target)
}
return err
}
func Unmount(mount string, flags int) error {
return unix.Unmount(mount, flags)
}
// UnmountAll repeatedly unmounts the given mount point until there
// are no mounts remaining (EINVAL is returned by mount), which is
// useful for undoing a stack of mounts on the same mount point.
func UnmountAll(mount string, flags int) error {
for {
if err := Unmount(mount, flags); err != nil {
// EINVAL is returned if the target is not a
// mount point, indicating that we are
// done. It can also indicate a few other
// things (such as invalid flags) which we
// unfortunately end up squelching here too.
if err == unix.EINVAL {
return nil
}
return err
}
}
}

14
server/server_solaris.go Normal file
View File

@ -0,0 +1,14 @@
package server
import "context"
const (
// DefaultAddress is the default unix socket address
DefaultAddress = "/var/run/containerd/containerd.sock"
// DefaultDebuggAddress is the default unix socket address for pprof data
DefaultDebugAddress = "/var/run/containerd/debug.sock"
)
func apply(_ context.Context, _ *Config) error {
return nil
}

View File

@ -1,4 +1,4 @@
// +build !linux,!windows
// +build !linux,!windows,!solaris
package server

View File

@ -1,4 +1,4 @@
// +build darwin freebsd
// +build darwin freebsd solaris
package snapshot

View File

@ -1,4 +1,4 @@
// +build linux
// +build linux,!no_btrfs
package btrfs

View File

@ -1,4 +1,4 @@
// +build linux
// +build linux,!no_btrfs
package btrfs

19
sys/stat_bsd.go Normal file
View File

@ -0,0 +1,19 @@
// +build darwin freebsd
package sys
import (
"syscall"
)
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
return st.Atimespec
}
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
return st.Ctimespec
}
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
return st.Mtimespec
}

19
sys/stat_unix.go Normal file
View File

@ -0,0 +1,19 @@
// +build linux solaris
package sys
import (
"syscall"
)
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
return st.Atim
}
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
return st.Ctim
}
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
return st.Mtim
}