mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Automated rollback of changelist 501671432
PiperOrigin-RevId: 504061302
This commit is contained in:
committed by
gVisor bot
parent
f8375fac10
commit
cf52b8a4a2
@@ -144,11 +144,6 @@ const (
|
||||
CgroupsWriteControlFiles = "Cgroups.WriteControlFiles"
|
||||
)
|
||||
|
||||
// ControlSocketAddr generates an abstract unix socket name for the given ID.
|
||||
func ControlSocketAddr(id string) string {
|
||||
return fmt.Sprintf("\x00runsc-sandbox.%s", id)
|
||||
}
|
||||
|
||||
// controller holds the control server, and is used for communication into the
|
||||
// sandbox.
|
||||
type controller struct {
|
||||
|
||||
@@ -104,7 +104,7 @@ func startGofer(root string) (int, func(), error) {
|
||||
}
|
||||
|
||||
func createLoader(spec *specs.Spec) (*Loader, func(), error) {
|
||||
fd, err := server.CreateSocket(ControlSocketAddr(fmt.Sprintf("%010d", rand.Int())[:10]))
|
||||
fd, err := server.CreateSocket(fmt.Sprintf("\x00loader-test.%010d", rand.Int())[:10])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -2683,3 +2684,43 @@ func TestSaveSystemdCgroup(t *testing.T) {
|
||||
t.Errorf("CompatCgroup not properly saved: want %v, got %v", cont.CompatCgroup, loadCont.CompatCgroup)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSandboxCommunicationUnshare checks that communication with sandboxes do
|
||||
// not require being in the same network namespace. This is required to allow
|
||||
// Kubernetes daemonsets/containers to communicate with sandboxes without the
|
||||
// need to join the host network namespaces.
|
||||
func TestSandboxCommunicationUnshare(t *testing.T) {
|
||||
spec, conf := sleepSpecConf(t)
|
||||
_, bundleDir, cleanup, err := testutil.SetupContainer(spec, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up container: %v", err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
args := Args{
|
||||
ID: testutil.RandomContainerID(),
|
||||
Spec: spec,
|
||||
BundleDir: bundleDir,
|
||||
}
|
||||
|
||||
cont, err := New(conf, args)
|
||||
if err != nil {
|
||||
t.Fatalf("Creating container: %v", err)
|
||||
}
|
||||
defer cont.Destroy()
|
||||
|
||||
if err := cont.Start(conf); err != nil {
|
||||
t.Fatalf("starting container: %v", err)
|
||||
}
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
if err := unix.Unshare(unix.CLONE_NEWNET); err != nil {
|
||||
t.Fatalf("unix.Unshare(): %v", err)
|
||||
}
|
||||
|
||||
// Send a simple command to test that the sandbox can be reached.
|
||||
if err := cont.SignalContainer(0, true); err != nil {
|
||||
t.Errorf("SignalContainer(): %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -65,6 +66,30 @@ const (
|
||||
namespaceAnnotation = "io.kubernetes.cri.sandbox-namespace"
|
||||
)
|
||||
|
||||
// createControlSocket finds a location and creates the socket used to
|
||||
// communicate with the sandbox.
|
||||
func createControlSocket(rootDir, id string) (string, int, error) {
|
||||
name := fmt.Sprintf("runsc-%s.sock", id)
|
||||
|
||||
// Only use absolute paths to guarantee resolution from anywhere.
|
||||
var paths []string
|
||||
for _, dir := range []string{rootDir, "/var/run", "/run", "/tmp"} {
|
||||
paths = append(paths, filepath.Join(dir, name))
|
||||
}
|
||||
// If nothing else worked, use the abstract namespace.
|
||||
paths = append(paths, fmt.Sprintf("\x00runsc-sandbox.%s", id))
|
||||
|
||||
for _, path := range paths {
|
||||
log.Debugf("Attempting to create socket file %q", path)
|
||||
fd, err := server.CreateSocket(path)
|
||||
if err == nil {
|
||||
log.Debugf("Using socket file %q", path)
|
||||
return path, fd, nil
|
||||
}
|
||||
}
|
||||
return "", -1, fmt.Errorf("unable to find location to write socket file")
|
||||
}
|
||||
|
||||
// pid is an atomic type that implements JSON marshal/unmarshal interfaces.
|
||||
type pid struct {
|
||||
val atomicbitops.Int64
|
||||
@@ -144,6 +169,9 @@ type Sandbox struct {
|
||||
// created.
|
||||
MetricServerAddress string `json:"metricServerAddress"`
|
||||
|
||||
// ControlAddress is the uRPC address used to connect to the sandbox.
|
||||
ControlAddress string `json:"control_address"`
|
||||
|
||||
// child is set if a sandbox process is a child of the current process.
|
||||
//
|
||||
// This field isn't saved to json, because only a creator of sandbox
|
||||
@@ -225,6 +253,7 @@ func New(conf *config.Config, args *Args) (*Sandbox, error) {
|
||||
s.PodName = args.Spec.Annotations[podNameAnnotation]
|
||||
s.Namespace = args.Spec.Annotations[namespaceAnnotation]
|
||||
}
|
||||
|
||||
// The Cleanup object cleans up partially created sandboxes when an error
|
||||
// occurs. Any errors occurring during cleanup itself are ignored.
|
||||
c := cleanup.Make(func() {
|
||||
@@ -514,7 +543,7 @@ func (s *Sandbox) Event(cid string) (*boot.EventOut, error) {
|
||||
|
||||
func (s *Sandbox) sandboxConnect() (*urpc.Client, error) {
|
||||
log.Debugf("Connecting to sandbox %q", s.ID)
|
||||
conn, err := client.ConnectTo(boot.ControlSocketAddr(s.ID))
|
||||
conn, err := client.ConnectTo(s.ControlAddress)
|
||||
if err != nil {
|
||||
return nil, s.connError(err)
|
||||
}
|
||||
@@ -622,12 +651,12 @@ func (s *Sandbox) createSandboxProcess(conf *config.Config, args *Args, startSyn
|
||||
}
|
||||
|
||||
// Create a socket for the control server and donate it to the sandbox.
|
||||
addr := boot.ControlSocketAddr(s.ID)
|
||||
sockFD, err := server.CreateSocket(addr)
|
||||
log.Infof("Creating sandbox process with addr: %s", addr[1:]) // skip "\00".
|
||||
controlAddress, sockFD, err := createControlSocket(conf.RootDir, s.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating control server socket for sandbox %q: %v", s.ID, err)
|
||||
return fmt.Errorf("creating control socket %q: %v", s.ControlAddress, err)
|
||||
}
|
||||
log.Infof("Control socket: %q", s.ControlAddress)
|
||||
s.ControlAddress = controlAddress
|
||||
donations.DonateAndClose("controller-fd", os.NewFile(uintptr(sockFD), "control_server_socket"))
|
||||
|
||||
specFile, err := specutils.OpenSpec(args.BundleDir)
|
||||
@@ -1000,6 +1029,12 @@ func (s *Sandbox) IsRootContainer(cid string) bool {
|
||||
// is idempotent.
|
||||
func (s *Sandbox) destroy() error {
|
||||
log.Debugf("Destroying sandbox %q", s.ID)
|
||||
// Only delete the control file if it exists and is not an abstract UDS.
|
||||
if len(s.ControlAddress) > 0 && s.ControlAddress[0] != 0 {
|
||||
if err := os.Remove(s.ControlAddress); err != nil {
|
||||
log.Warningf("failed to delete control socket file %q: %v", s.ControlAddress, err)
|
||||
}
|
||||
}
|
||||
pid := s.Pid.load()
|
||||
if pid != 0 {
|
||||
log.Debugf("Killing sandbox %q", s.ID)
|
||||
|
||||
Reference in New Issue
Block a user