Skip to content

Commit

Permalink
[#137] FreeBSD support
Browse files Browse the repository at this point in the history
Now that containerd supports FreeBSD, we can port nerdctl, too!
:rocket:. For full-fledged functionality, we will need to port

* buildkit. Status: POC is ready, need to upstream fixes to
  dependencies.
* runtime + containerd shim. runj/knast should work just fine.
* CNI bridge plugin for networking.

This change fixes FreeBSD compilation errors by renaming linux files
to unix where necessary, or otherwise introducing FreeBSD versions for
the necessary files.

Signed-off-by: Artem Khramov <akhramov@pm.me>
  • Loading branch information
akhramov committed Sep 15, 2021
1 parent 04bc79a commit 1ca61e2
Show file tree
Hide file tree
Showing 17 changed files with 466 additions and 90 deletions.
3 changes: 3 additions & 0 deletions cmd/nerdctl/client_linux.go → cmd/nerdctl/client_unix.go
@@ -1,3 +1,6 @@
//go:build freebsd || linux
// +build freebsd linux

/*
Copyright The containerd Authors.
Expand Down
29 changes: 29 additions & 0 deletions cmd/nerdctl/exec_freebsd.go
@@ -0,0 +1,29 @@
//go:build freebsd
// +build freebsd

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"github.com/opencontainers/runtime-spec/specs-go"
)

func setExecCapabilities(pspec *specs.Process) error {
//no op freebsd
return nil
}
3 changes: 3 additions & 0 deletions cmd/nerdctl/login_linux.go → cmd/nerdctl/login_unix.go
@@ -1,3 +1,6 @@
//go:build freebsd || linux
// +build freebsd linux

/*
Copyright The containerd Authors.
Expand Down
40 changes: 40 additions & 0 deletions cmd/nerdctl/main_freebsd.go
@@ -0,0 +1,40 @@
//go:build freebsd
// +build freebsd

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"github.com/urfave/cli/v2"
)

func appNeedsRootlessParentMain(clicontext *cli.Context) bool {
return false
}

func appBashComplete(clicontext *cli.Context) {
return
}

func bashCompleteNamespaceNames(clicontext *cli.Context) {
return
}

func bashCompleteSnapshotterNames(clicontext *cli.Context) {
return
}
11 changes: 8 additions & 3 deletions cmd/nerdctl/run.go
Expand Up @@ -25,6 +25,7 @@ import (
"os"
"path"
"path/filepath"
"runtime"
"strings"

"github.com/containerd/console"
Expand Down Expand Up @@ -315,12 +316,16 @@ func runAction(clicontext *cli.Context) error {
opts = append(opts,
oci.WithDefaultSpec(),
oci.WithDefaultUnixDevices,
oci.WithMounts([]specs.Mount{
{Type: "cgroup", Source: "cgroup", Destination: "/sys/fs/cgroup", Options: []string{"ro", "nosuid", "noexec", "nodev"}},
}),
WithoutRunMount(), // unmount default tmpfs on "/run": https://github.com/containerd/nerdctl/issues/157
)

if runtime.GOOS != "freebsd" {
opts = append(opts,
oci.WithMounts([]specs.Mount{
{Type: "cgroup", Source: "cgroup", Destination: "/sys/fs/cgroup", Options: []string{"ro", "nosuid", "noexec", "nodev"}},
}))
}

rootfsOpts, rootfsCOpts, ensuredImage, err := generateRootfsOpts(ctx, client, clicontext, id)
if err != nil {
return err
Expand Down
29 changes: 29 additions & 0 deletions cmd/nerdctl/run_cgroup_freebsd.go
@@ -0,0 +1,29 @@
//go:build freebsd
// +build freebsd

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"github.com/containerd/containerd/oci"
"github.com/urfave/cli/v2"
)

func generateCgroupOpts(clicontext *cli.Context, id string) ([]oci.SpecOpts, error) {
return []oci.SpecOpts{}, nil
}
37 changes: 37 additions & 0 deletions cmd/nerdctl/run_freebsd.go
@@ -0,0 +1,37 @@
//go:build freebsd
// +build freebsd

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"context"

"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/oci"
"github.com/urfave/cli/v2"
)

func runBashComplete(clicontext *cli.Context) {
// noop
}

func WithoutRunMount() func(ctx context.Context, client oci.Client, c *containers.Container, s *oci.Spec) error {
// not valid on windows
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error { return nil }
}
32 changes: 32 additions & 0 deletions pkg/containerinspector/containerinspector_freebsd.go
@@ -0,0 +1,32 @@
//go:build freebsd
// +build freebsd

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package containerinspector

import (
"context"

"github.com/containerd/nerdctl/pkg/inspecttypes/native"
)

func inspectNetNS(ctx context.Context, pid int) (*native.NetNS, error) {
r := &native.NetNS{}

return r, nil
}
51 changes: 51 additions & 0 deletions pkg/defaults/defaults_freebsd.go
@@ -0,0 +1,51 @@
//go:build freebsd
// +build freebsd

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package defaults

import (
gocni "github.com/containerd/go-cni"
)

const AppArmorProfileName = "nerdctl-default"

func DataRoot() string {
return "/var/lib/nerdctl"
}

func CNIPath() string {
// default: /opt/cni/bin
return gocni.DefaultCNIDir
}

func CNINetConfPath() string {
return gocni.DefaultNetDir
}

func BuildKitHost() string {
return "unix:///run/buildkit/buildkitd.sock"
}

func CgroupManager() string {
return ""
}

func CgroupnsMode() string {
return ""
}
26 changes: 26 additions & 0 deletions pkg/infoutil/infoutil_freebsd.go
@@ -0,0 +1,26 @@
//go:build freebsd
// +build freebsd

/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package infoutil

const UnameO = "FreeBSD"

func CgroupsVersion() string {
return ""
}
87 changes: 0 additions & 87 deletions pkg/infoutil/infoutil_linux.go
Expand Up @@ -17,98 +17,11 @@
package infoutil

import (
"bufio"
"io"
"os"
"regexp"

"strings"

"github.com/containerd/cgroups"
"golang.org/x/sys/unix"
)

// UnameR returns `uname -r`
func UnameR() string {
var utsname unix.Utsname
if err := unix.Uname(&utsname); err != nil {
// error is unlikely to happen
return ""
}
var s string
for _, f := range utsname.Release {
if f == 0 {
break
}
s += string(f)
}
return s
}

// UnameM returns `uname -m`
func UnameM() string {
var utsname unix.Utsname
if err := unix.Uname(&utsname); err != nil {
// error is unlikely to happen
return ""
}
var s string
for _, f := range utsname.Machine {
if f == 0 {
break
}
s += string(f)
}
return s
}

const UnameO = "GNU/Linux"

func DistroName() string {
f, err := os.Open("/etc/os-release")
if err != nil {
return UnameO
}
defer f.Close()
return distroName(f)
}

func distroName(r io.Reader) string {
scanner := bufio.NewScanner(r)
var name, version string
for scanner.Scan() {
line := scanner.Text()
k, v := getOSReleaseAttrib(line)
switch k {
case "PRETTY_NAME":
return v
case "NAME":
name = v
case "VERSION":
version = v
}
}
if name != "" {
if version != "" {
return name + " " + version
}
return name
}
return UnameO
}

var osReleaseAttribRegex = regexp.MustCompile(`([^\s=]+)\s*=\s*("{0,1})([^"]*)("{0,1})`)

func getOSReleaseAttrib(line string) (string, string) {
splitBySlash := strings.SplitN(line, "#", 2)
l := strings.TrimSpace(splitBySlash[0])
x := osReleaseAttribRegex.FindAllStringSubmatch(l, -1)
if len(x) >= 1 && len(x[0]) > 3 {
return x[0][1], x[0][3]
}
return "", ""
}

func CgroupsVersion() string {
if cgroups.Mode() == cgroups.Unified {
return "2"
Expand Down

0 comments on commit 1ca61e2

Please sign in to comment.