Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 46 additions & 47 deletions cmd/rootlesskit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,37 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
"strconv"
"strings"
"syscall"

"github.com/Masterminds/semver/v3"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"

"github.com/rootless-containers/rootlesskit/v2/pkg/systemd/activation"
"github.com/rootless-containers/rootlesskit/v2/pkg/child"
"github.com/rootless-containers/rootlesskit/v2/pkg/common"
"github.com/rootless-containers/rootlesskit/v2/pkg/copyup/tmpfssymlink"
"github.com/rootless-containers/rootlesskit/v2/pkg/network/lxcusernic"
"github.com/rootless-containers/rootlesskit/v2/pkg/network/none"
"github.com/rootless-containers/rootlesskit/v2/pkg/network/pasta"
"github.com/rootless-containers/rootlesskit/v2/pkg/network/slirp4netns"
"github.com/rootless-containers/rootlesskit/v2/pkg/network/vpnkit"
"github.com/rootless-containers/rootlesskit/v2/pkg/network/none"
"github.com/rootless-containers/rootlesskit/v2/pkg/parent"
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin"
"github.com/rootless-containers/rootlesskit/v2/pkg/port/portutil"
slirp4netns_port "github.com/rootless-containers/rootlesskit/v2/pkg/port/slirp4netns"
"github.com/rootless-containers/rootlesskit/v2/pkg/systemd/activation"
"github.com/rootless-containers/rootlesskit/v2/pkg/version"
)


const (
pipeFDEnvKey = "_ROOTLESSKIT_PIPEFD_UNDOCUMENTED"
childUseActivationEnvKey = "_ROOTLESSKIT_SYSTEMD_ACTIVATION_CHILD_USE_UNDOCUMENTED"
runActivationHelperEnvKey = "_ROOTLESSKIT_SYSTEMD_ACTIVATION_RUN_HELPER_UNDOCUMENTED"
stateDirEnvKey = "ROOTLESSKIT_STATE_DIR" // documented
parentEUIDEnvKey = "ROOTLESSKIT_PARENT_EUID" // documented
parentEGIDEnvKey = "ROOTLESSKIT_PARENT_EGID" // documented
pipeFDEnvKey = "_ROOTLESSKIT_PIPEFD_UNDOCUMENTED"
childUseActivationEnvKey = "_ROOTLESSKIT_SYSTEMD_ACTIVATION_CHILD_USE_UNDOCUMENTED"
runActivationHelperEnvKey = "_ROOTLESSKIT_SYSTEMD_ACTIVATION_RUN_HELPER_UNDOCUMENTED"
stateDirEnvKey = "ROOTLESSKIT_STATE_DIR" // documented
parentEUIDEnvKey = "ROOTLESSKIT_PARENT_EUID" // documented
parentEGIDEnvKey = "ROOTLESSKIT_PARENT_EGID" // documented
)

func main() {
Expand All @@ -48,7 +47,7 @@ func main() {
if iAmChild {
id = "child " // padded to len("parent")
} else if iAmActivationHelper {
id = "activation_helper"
id = "activation_helper"
}
debug := false
app := cli.NewApp()
Expand Down Expand Up @@ -262,12 +261,12 @@ OPTIONS:
return errors.New("no command specified")
}
if iAmActivationHelper {
activationOpt, err := createActivationOpts(clicontext)
if err != nil {
return err
}
return activation.ActivationHelper(activationOpt)
}
activationOpt, err := createActivationOpts(clicontext)
if err != nil {
return err
}
return activation.ActivationHelper(activationOpt)
}
if iAmChild {
childOpt, err := createChildOpt(clicontext)
if err != nil {
Expand Down Expand Up @@ -323,19 +322,19 @@ func parseCIDR(s string) (*net.IPNet, error) {
func createParentOpt(clicontext *cli.Context) (parent.Opt, error) {
var err error
opt := parent.Opt{
PipeFDEnvKey: pipeFDEnvKey,
StateDirEnvKey: stateDirEnvKey,
PipeFDEnvKey: pipeFDEnvKey,
StateDirEnvKey: stateDirEnvKey,
ChildUseActivationEnvKey: childUseActivationEnvKey,
CreatePIDNS: clicontext.Bool("pidns"),
CreateCgroupNS: clicontext.Bool("cgroupns"),
CreateUTSNS: clicontext.Bool("utsns"),
CreateIPCNS: clicontext.Bool("ipcns"),
DetachNetNS: clicontext.Bool("detach-netns"),
ParentEUIDEnvKey: parentEUIDEnvKey,
ParentEGIDEnvKey: parentEGIDEnvKey,
Propagation: clicontext.String("propagation"),
EvacuateCgroup2: clicontext.String("evacuate-cgroup2"),
SubidSource: parent.SubidSource(clicontext.String("subid-source")),
CreatePIDNS: clicontext.Bool("pidns"),
CreateCgroupNS: clicontext.Bool("cgroupns"),
CreateUTSNS: clicontext.Bool("utsns"),
CreateIPCNS: clicontext.Bool("ipcns"),
DetachNetNS: clicontext.Bool("detach-netns"),
ParentEUIDEnvKey: parentEUIDEnvKey,
ParentEGIDEnvKey: parentEGIDEnvKey,
Propagation: clicontext.String("propagation"),
EvacuateCgroup2: clicontext.String("evacuate-cgroup2"),
SubidSource: parent.SubidSource(clicontext.String("subid-source")),
}
if opt.EvacuateCgroup2 != "" {
if !opt.CreateCgroupNS {
Expand Down Expand Up @@ -595,15 +594,15 @@ func createChildOpt(clicontext *cli.Context) (child.Opt, error) {
pidns := clicontext.Bool("pidns")
detachNetNS := clicontext.Bool("detach-netns")
opt := child.Opt{
PipeFDEnvKey: pipeFDEnvKey,
PipeFDEnvKey: pipeFDEnvKey,
RunActivationHelperEnvKey: runActivationHelperEnvKey,
ChildUseActivationEnvKey: childUseActivationEnvKey,
StateDirEnvKey: stateDirEnvKey,
TargetCmd: clicontext.Args().Slice(),
MountProcfs: pidns,
DetachNetNS: detachNetNS,
Propagation: clicontext.String("propagation"),
EvacuateCgroup2: clicontext.String("evacuate-cgroup2") != "",
ChildUseActivationEnvKey: childUseActivationEnvKey,
StateDirEnvKey: stateDirEnvKey,
TargetCmd: clicontext.Args().Slice(),
MountProcfs: pidns,
DetachNetNS: detachNetNS,
Propagation: clicontext.String("propagation"),
EvacuateCgroup2: clicontext.String("evacuate-cgroup2") != "",
}
switch reaperStr := clicontext.String("reaper"); reaperStr {
case "auto":
Expand Down Expand Up @@ -684,21 +683,21 @@ func unameM() string {
}

func checkActivationHelper() bool {
envValue, envSet := os.LookupEnv(runActivationHelperEnvKey)
if !envSet {
return false
}
envValue, envSet := os.LookupEnv(runActivationHelperEnvKey)
if !envSet {
return false
}
activationHelperValue, err := strconv.ParseBool(envValue)
if err != nil {
panic(fmt.Sprintf("Env variable [%s] is set to [%s] and cannot be parsed", runActivationHelperEnvKey, envValue))
panic(fmt.Sprintf("Env variable [%s] is set to [%s] and cannot be parsed", runActivationHelperEnvKey, envValue))
}
return activationHelperValue
}

func createActivationOpts(clicontext *cli.Context) (activation.Opt, error) {
opt := activation.Opt {
RunActivationHelperEnvKey: runActivationHelperEnvKey,
TargetCmd: clicontext.Args().Slice(),
}
return opt, nil
opt := activation.Opt{
RunActivationHelperEnvKey: runActivationHelperEnvKey,
TargetCmd: clicontext.Args().Slice(),
}
return opt, nil
}
67 changes: 33 additions & 34 deletions pkg/child/child.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,29 @@ func setupFiles(cmd *exec.Cmd) {
}
}
for fd := 0; fd < systemdActivationFDs; fd++ {
cmd.ExtraFiles[fd] = os.NewFile(uintptr(firstExtraFD + fd), "")
cmd.ExtraFiles[fd] = os.NewFile(uintptr(firstExtraFD+fd), "")
}
}


func createCmd(opt Opt) (*exec.Cmd, error) {
fixListenPidEnv, err := strconv.ParseBool(os.Getenv(opt.ChildUseActivationEnvKey))
if err != nil {
fixListenPidEnv = false
}
os.Unsetenv(opt.ChildUseActivationEnvKey)
targetCmd := opt.TargetCmd
var cmd *exec.Cmd
cmdEnv := os.Environ()
if fixListenPidEnv {
cmd = exec.Command("/proc/self/exe", os.Args[1:]...)
cmdEnv = append(cmdEnv, opt.RunActivationHelperEnvKey + "=true")
} else {
var args []string
if len(targetCmd) > 1 {
args = targetCmd[1:]
}
cmd = exec.Command(targetCmd[0], args...)
}
fixListenPidEnv, err := strconv.ParseBool(os.Getenv(opt.ChildUseActivationEnvKey))
if err != nil {
fixListenPidEnv = false
}
os.Unsetenv(opt.ChildUseActivationEnvKey)
targetCmd := opt.TargetCmd
var cmd *exec.Cmd
cmdEnv := os.Environ()
if fixListenPidEnv {
cmd = exec.Command("/proc/self/exe", os.Args[1:]...)
cmdEnv = append(cmdEnv, opt.RunActivationHelperEnvKey+"=true")
} else {
var args []string
if len(targetCmd) > 1 {
args = targetCmd[1:]
}
cmd = exec.Command(targetCmd[0], args...)
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand Down Expand Up @@ -271,20 +270,20 @@ func setupNet(stateDir string, msg *messages.ParentInitNetworkDriverCompleted, e
}

type Opt struct {
PipeFDEnvKey string // needs to be set
RunActivationHelperEnvKey string // needs to be set
ChildUseActivationEnvKey string // needs to be set
StateDirEnvKey string // needs to be set
TargetCmd []string // needs to be set
NetworkDriver network.ChildDriver // nil for HostNetwork
CopyUpDriver copyup.ChildDriver // cannot be nil if len(CopyUpDirs) != 0
CopyUpDirs []string
DetachNetNS bool
PortDriver port.ChildDriver
MountProcfs bool // needs to be set if (and only if) parent.Opt.CreatePIDNS is set
Propagation string // mount propagation type
Reaper bool
EvacuateCgroup2 bool // needs to correspond to parent.Opt.EvacuateCgroup2 is set
PipeFDEnvKey string // needs to be set
RunActivationHelperEnvKey string // needs to be set
ChildUseActivationEnvKey string // needs to be set
StateDirEnvKey string // needs to be set
TargetCmd []string // needs to be set
NetworkDriver network.ChildDriver // nil for HostNetwork
CopyUpDriver copyup.ChildDriver // cannot be nil if len(CopyUpDirs) != 0
CopyUpDirs []string
DetachNetNS bool
PortDriver port.ChildDriver
MountProcfs bool // needs to be set if (and only if) parent.Opt.CreatePIDNS is set
Propagation string // mount propagation type
Reaper bool
EvacuateCgroup2 bool // needs to correspond to parent.Opt.EvacuateCgroup2 is set
}

// statPIDNS is from https://github.com/containerd/containerd/blob/v1.7.2/services/introspection/pidns_linux.go#L25-L36
Expand Down
2 changes: 1 addition & 1 deletion pkg/network/lxcusernic/lxcusernic.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func exchangeDHCP(c *client4.Client, dev string, detachedNetNSPath string) (*dhc
}

func (d *childDriver) ChildDriverInfo() (*network.ChildDriverInfo, error) {
return &network.ChildDriverInfo {
return &network.ChildDriverInfo{
ConfiguresInterface: false,
}, nil
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/network/pasta/pasta.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ func (d *parentDriver) ConfigureNetwork(childPID int, stateDir, detachedNetNSPat
exitErr := &exec.ExitError{}
if errors.As(err, &exitErr) {
return nil, common.Seq(cleanups),
fmt.Errorf("pasta failed with exit code %d:\n%s",
exitErr.ExitCode(), string(out))
fmt.Errorf("pasta failed with exit code %d:\n%s",
exitErr.ExitCode(), string(out))
}
return nil, common.Seq(cleanups), fmt.Errorf("executing %v: %w", cmd, err)
}
Expand Down Expand Up @@ -188,7 +188,7 @@ type childDriver struct {
}

func (d *childDriver) ChildDriverInfo() (*network.ChildDriverInfo, error) {
return &network.ChildDriverInfo {
return &network.ChildDriverInfo{
ConfiguresInterface: true,
}, nil
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/network/slirp4netns/slirp4netns.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ type childDriver struct {
}

func (d *childDriver) ChildDriverInfo() (*network.ChildDriverInfo, error) {
return &network.ChildDriverInfo {
return &network.ChildDriverInfo{
ConfiguresInterface: false,
}, nil
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/network/vpnkit/vpnkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ type childDriver struct {
}

func (d *childDriver) ChildDriverInfo() (*network.ChildDriverInfo, error) {
return &network.ChildDriverInfo {
return &network.ChildDriverInfo{
ConfiguresInterface: false,
}, nil
}
Expand Down
50 changes: 25 additions & 25 deletions pkg/parent/parent.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,23 @@ import (
)

type Opt struct {
PipeFDEnvKey string // needs to be set
ChildUseActivationEnvKey string // needs to be set
StateDir string // directory needs to be precreated
StateDirEnvKey string // optional env key to propagate StateDir value
NetworkDriver network.ParentDriver // nil for HostNetwork
PortDriver port.ParentDriver // nil for --port-driver=none
PublishPorts []port.Spec
CreatePIDNS bool
CreateCgroupNS bool
CreateUTSNS bool
CreateIPCNS bool
DetachNetNS bool
ParentEUIDEnvKey string // optional env key to propagate geteuid() value
ParentEGIDEnvKey string // optional env key to propagate getegid() value
Propagation string
EvacuateCgroup2 string // e.g. "rootlesskit_evacuation"
SubidSource SubidSource
PipeFDEnvKey string // needs to be set
ChildUseActivationEnvKey string // needs to be set
StateDir string // directory needs to be precreated
StateDirEnvKey string // optional env key to propagate StateDir value
NetworkDriver network.ParentDriver // nil for HostNetwork
PortDriver port.ParentDriver // nil for --port-driver=none
PublishPorts []port.Spec
CreatePIDNS bool
CreateCgroupNS bool
CreateUTSNS bool
CreateIPCNS bool
DetachNetNS bool
ParentEUIDEnvKey string // optional env key to propagate geteuid() value
ParentEGIDEnvKey string // optional env key to propagate getegid() value
Propagation string
EvacuateCgroup2 string // e.g. "rootlesskit_evacuation"
SubidSource SubidSource
}

type SubidSource string
Expand Down Expand Up @@ -133,18 +133,18 @@ func setupFilesAndEnv(readPipe *os.File, writePipe *os.File, opt Opt) ([]*os.Fil
listenFds, listenFdsErr := strconv.Atoi(os.Getenv("LISTEN_FDS"))
useSystemdSocketFDs := listenPidErr == nil && listenFdsErr == nil && listenFds > 0
if !useSystemdSocketFDs {
listenFds = 0
listenFds = 0
}
extraFiles := make([]*os.File, listenFds + 2)
for i, fd := 0, listenFdsStart; i < listenFds; i, fd = i + 1, fd + 1 {
name := "LISTEN_FD_" + strconv.Itoa(fd)
extraFiles[i] = os.NewFile(uintptr(fd), name)
extraFiles := make([]*os.File, listenFds+2)
for i, fd := 0, listenFdsStart; i < listenFds; i, fd = i+1, fd+1 {
name := "LISTEN_FD_" + strconv.Itoa(fd)
extraFiles[i] = os.NewFile(uintptr(fd), name)
}
extraFiles[listenFds] = readPipe
extraFiles[listenFds + 1] = writePipe
extraFiles[listenFds+1] = writePipe
cmdEnv := os.Environ()
cmdEnv = append(cmdEnv, opt.PipeFDEnvKey + "=" + strconv.Itoa(listenFdsStart + listenFds) + "," + strconv.Itoa(listenFdsStart + listenFds + 1))
cmdEnv = append(cmdEnv, opt.ChildUseActivationEnvKey + "=" + strconv.FormatBool(listenPid == os.Getpid()))
cmdEnv = append(cmdEnv, opt.PipeFDEnvKey+"="+strconv.Itoa(listenFdsStart+listenFds)+","+strconv.Itoa(listenFdsStart+listenFds+1))
cmdEnv = append(cmdEnv, opt.ChildUseActivationEnvKey+"="+strconv.FormatBool(listenPid == os.Getpid()))
return extraFiles, cmdEnv
}

Expand Down
Loading