mirror of
https://github.com/containers/podman.git
synced 2025-06-20 00:51:16 +08:00
Merge pull request #15632 from dfr/freebsd-container
Add support for FreeBSD containers
This commit is contained in:
@ -1133,20 +1133,6 @@ func (c *Container) NetworkDisabled() (bool, error) {
|
||||
return networkDisabled(c)
|
||||
}
|
||||
|
||||
func networkDisabled(c *Container) (bool, error) {
|
||||
if c.config.CreateNetNS {
|
||||
return false, nil
|
||||
}
|
||||
if !c.config.PostConfigureNetNS {
|
||||
for _, ns := range c.config.Spec.Linux.Namespaces {
|
||||
if ns.Type == spec.NetworkNamespace {
|
||||
return ns.Path == "", nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (c *Container) HostNetwork() bool {
|
||||
if c.config.CreateNetNS || c.config.NetNsCtr != "" {
|
||||
return false
|
||||
|
@ -10,3 +10,13 @@ type containerPlatformState struct {
|
||||
// namespace.
|
||||
NetworkJail string `json:"-"`
|
||||
}
|
||||
|
||||
func networkDisabled(c *Container) (bool, error) {
|
||||
if c.config.CreateNetNS {
|
||||
return false, nil
|
||||
}
|
||||
if !c.config.PostConfigureNetNS {
|
||||
return c.state.NetworkJail == "", nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
2699
libpod/container_internal_common.go
Normal file
2699
libpod/container_internal_common.go
Normal file
File diff suppressed because it is too large
Load Diff
285
libpod/container_internal_freebsd.go
Normal file
285
libpod/container_internal_freebsd.go
Normal file
@ -0,0 +1,285 @@
|
||||
//go:build freebsd
|
||||
// +build freebsd
|
||||
|
||||
package libpod
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containers/common/libnetwork/types"
|
||||
"github.com/containers/podman/v4/pkg/rootless"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
bindOptions = []string{}
|
||||
)
|
||||
|
||||
// Network stubs to decouple container_internal_freebsd.go from
|
||||
// networking_freebsd.go so they can be reviewed separately.
|
||||
func (r *Runtime) createNetNS(ctr *Container) (netJail string, q map[string]types.StatusBlock, retErr error) {
|
||||
return "", nil, errors.New("not implemented (*Runtime) createNetNS")
|
||||
}
|
||||
|
||||
func (r *Runtime) teardownNetNS(ctr *Container) error {
|
||||
return errors.New("not implemented (*Runtime) teardownNetNS")
|
||||
}
|
||||
|
||||
func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.StatusBlock, error) {
|
||||
return nil, errors.New("not implemented (*Runtime) reloadContainerNetwork")
|
||||
}
|
||||
|
||||
func (c *Container) mountSHM(shmOptions string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) unmountSHM(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepare mounts the container and sets up other required resources like net
|
||||
// namespaces
|
||||
func (c *Container) prepare() error {
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
jailName string
|
||||
networkStatus map[string]types.StatusBlock
|
||||
createNetNSErr, mountStorageErr error
|
||||
mountPoint string
|
||||
tmpStateLock sync.Mutex
|
||||
)
|
||||
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
// Set up network namespace if not already set up
|
||||
noNetNS := c.state.NetworkJail == ""
|
||||
if c.config.CreateNetNS && noNetNS && !c.config.PostConfigureNetNS {
|
||||
jailName, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
|
||||
if createNetNSErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tmpStateLock.Lock()
|
||||
defer tmpStateLock.Unlock()
|
||||
|
||||
// Assign NetNS attributes to container
|
||||
c.state.NetworkJail = jailName
|
||||
c.state.NetworkStatus = networkStatus
|
||||
}
|
||||
}()
|
||||
// Mount storage if not mounted
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
mountPoint, mountStorageErr = c.mountStorage()
|
||||
|
||||
if mountStorageErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tmpStateLock.Lock()
|
||||
defer tmpStateLock.Unlock()
|
||||
|
||||
// Finish up mountStorage
|
||||
c.state.Mounted = true
|
||||
c.state.Mountpoint = mountPoint
|
||||
|
||||
logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
var createErr error
|
||||
if mountStorageErr != nil {
|
||||
if createErr != nil {
|
||||
logrus.Errorf("Preparing container %s: %v", c.ID(), createErr)
|
||||
}
|
||||
createErr = mountStorageErr
|
||||
}
|
||||
|
||||
if createErr != nil {
|
||||
return createErr
|
||||
}
|
||||
|
||||
// Save changes to container state
|
||||
if err := c.save(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanupNetwork unmounts and cleans up the container's network
|
||||
func (c *Container) cleanupNetwork() error {
|
||||
if c.config.NetNsCtr != "" {
|
||||
return nil
|
||||
}
|
||||
netDisabled, err := c.NetworkDisabled()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if netDisabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop the container's network namespace (if it has one)
|
||||
if err := c.runtime.teardownNetNS(c); err != nil {
|
||||
logrus.Errorf("Unable to cleanup network for container %s: %q", c.ID(), err)
|
||||
}
|
||||
|
||||
if c.valid {
|
||||
return c.save()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// reloadNetwork reloads the network for the given container, recreating
|
||||
// firewall rules.
|
||||
func (c *Container) reloadNetwork() error {
|
||||
result, err := c.runtime.reloadContainerNetwork(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.state.NetworkStatus = result
|
||||
|
||||
return c.save()
|
||||
}
|
||||
|
||||
// Add an existing container's network jail
|
||||
func (c *Container) addNetworkContainer(g *generate.Generator, ctr string) error {
|
||||
nsCtr, err := c.runtime.state.Container(ctr)
|
||||
c.runtime.state.UpdateContainer(nsCtr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving dependency %s of container %s from state: %w", ctr, c.ID(), err)
|
||||
}
|
||||
g.AddAnnotation("org.freebsd.parentJail", nsCtr.state.NetworkJail)
|
||||
return nil
|
||||
}
|
||||
|
||||
func isRootlessCgroupSet(cgroup string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Container) expectPodCgroup() (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (c *Container) getOCICgroupPath() (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func openDirectory(path string) (fd int, err error) {
|
||||
const O_PATH = 0x00400000
|
||||
return unix.Open(path, unix.O_RDONLY|O_PATH, 0)
|
||||
}
|
||||
|
||||
func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
||||
if c.config.CreateNetNS {
|
||||
g.AddAnnotation("org.freebsd.parentJail", c.state.NetworkJail)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) addSystemdMounts(g *generate.Generator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) addSharedNamespaces(g *generate.Generator) error {
|
||||
if c.config.NetNsCtr != "" {
|
||||
if err := c.addNetworkContainer(g, c.config.NetNsCtr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
availableUIDs, availableGIDs, err := rootless.GetAvailableIDMaps()
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// The kernel-provided files only exist if user namespaces are supported
|
||||
logrus.Debugf("User or group ID mappings not available: %s", err)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
g.Config.Linux.UIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.UIDMappings, availableUIDs)
|
||||
g.Config.Linux.GIDMappings = rootless.MaybeSplitMappings(g.Config.Linux.GIDMappings, availableGIDs)
|
||||
}
|
||||
|
||||
// Hostname handling:
|
||||
// If we have a UTS namespace, set Hostname in the OCI spec.
|
||||
// Set the HOSTNAME environment variable unless explicitly overridden by
|
||||
// the user (already present in OCI spec). If we don't have a UTS ns,
|
||||
// set it to the host's hostname instead.
|
||||
hostname := c.Hostname()
|
||||
foundUTS := false
|
||||
|
||||
// TODO: make this optional, needs progress on adding FreeBSD section to the spec
|
||||
foundUTS = true
|
||||
g.SetHostname(hostname)
|
||||
|
||||
if !foundUTS {
|
||||
tmpHostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hostname = tmpHostname
|
||||
}
|
||||
needEnv := true
|
||||
for _, checkEnv := range g.Config.Process.Env {
|
||||
if strings.SplitN(checkEnv, "=", 2)[0] == "HOSTNAME" {
|
||||
needEnv = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if needEnv {
|
||||
g.AddProcessEnv("HOSTNAME", hostname)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) addRootPropagation(g *generate.Generator, mounts []spec.Mount) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) setProcessLabel(g *generate.Generator) {
|
||||
}
|
||||
|
||||
func (c *Container) setMountLabel(g *generate.Generator) {
|
||||
}
|
||||
|
||||
func (c *Container) setCgroupsPath(g *generate.Generator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) addSlirp4netnsDNS(nameservers []string) []string {
|
||||
return nameservers
|
||||
}
|
||||
|
||||
func (c *Container) isSlirp4netnsIPv6() (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// check for net=none
|
||||
func (c *Container) hasNetNone() bool {
|
||||
return c.state.NetworkJail == ""
|
||||
}
|
||||
|
||||
func setVolumeAtime(mountPoint string, st os.FileInfo) error {
|
||||
stat := st.Sys().(*syscall.Stat_t)
|
||||
atime := time.Unix(int64(stat.Atimespec.Sec), int64(stat.Atimespec.Nsec)) //nolint: unconvert
|
||||
if err := os.Chtimes(mountPoint, atime, st.ModTime()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
//go:build !linux && !freebsd
|
||||
// +build !linux,!freebsd
|
||||
|
||||
package libpod
|
||||
|
||||
|
@ -5,6 +5,7 @@ package libpod
|
||||
|
||||
import (
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
type containerPlatformState struct {
|
||||
@ -13,3 +14,17 @@ type containerPlatformState struct {
|
||||
// told to join another container's network namespace
|
||||
NetNS ns.NetNS `json:"-"`
|
||||
}
|
||||
|
||||
func networkDisabled(c *Container) (bool, error) {
|
||||
if c.config.CreateNetNS {
|
||||
return false, nil
|
||||
}
|
||||
if !c.config.PostConfigureNetNS {
|
||||
for _, ns := range c.config.Spec.Linux.Namespaces {
|
||||
if ns.Type == spec.NetworkNamespace {
|
||||
return ns.Path == "", nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ package libpod
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containers/common/libnetwork/types"
|
||||
@ -84,3 +85,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
|
||||
func (c *Container) convertPortMappings() []types.PortMapping {
|
||||
return []types.PortMapping{}
|
||||
}
|
||||
|
||||
func GetSlirp4netnsIP(subnet *net.IPNet) (*net.IP, error) {
|
||||
return nil, errors.New("not implemented GetSlirp4netnsIP")
|
||||
}
|
||||
|
@ -171,12 +171,17 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
|
||||
if config == nil {
|
||||
ctr.config.ID = stringid.GenerateNonCryptoID()
|
||||
size, err := units.FromHumanSize(r.config.Containers.ShmSize)
|
||||
if useDevShm {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("converting containers.conf ShmSize %s to an int: %w", r.config.Containers.ShmSize, err)
|
||||
}
|
||||
ctr.config.ShmSize = size
|
||||
ctr.config.NoShm = false
|
||||
ctr.config.NoShmShare = false
|
||||
} else {
|
||||
ctr.config.NoShm = true
|
||||
ctr.config.NoShmShare = true
|
||||
}
|
||||
ctr.config.StopSignal = 15
|
||||
|
||||
ctr.config.StopTimeout = r.config.Engine.StopTimeout
|
||||
@ -528,7 +533,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
||||
}
|
||||
}
|
||||
|
||||
if !MountExists(ctr.config.Spec.Mounts, "/dev/shm") && ctr.config.ShmDir == "" && !ctr.config.NoShm {
|
||||
if useDevShm && !MountExists(ctr.config.Spec.Mounts, "/dev/shm") && ctr.config.ShmDir == "" && !ctr.config.NoShm {
|
||||
ctr.config.ShmDir = filepath.Join(ctr.bundlePath(), "shm")
|
||||
if err := os.MkdirAll(ctr.config.ShmDir, 0700); err != nil {
|
||||
if !os.IsExist(err) {
|
||||
|
5
libpod/runtime_ctr_freebsd.go
Normal file
5
libpod/runtime_ctr_freebsd.go
Normal file
@ -0,0 +1,5 @@
|
||||
package libpod
|
||||
|
||||
const (
|
||||
useDevShm = false
|
||||
)
|
5
libpod/runtime_ctr_linux.go
Normal file
5
libpod/runtime_ctr_linux.go
Normal file
@ -0,0 +1,5 @@
|
||||
package libpod
|
||||
|
||||
const (
|
||||
useDevShm = true
|
||||
)
|
@ -5,8 +5,14 @@ package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
)
|
||||
|
||||
func GetContainerPidInformationDescriptors() ([]string, error) {
|
||||
return []string{}, errors.New("this function is not supported on freebsd")
|
||||
}
|
||||
|
||||
func AddPrivilegedDevices(g *generate.Generator) error {
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user