Skip to content
This repository has been archived by the owner on Jan 4, 2022. It is now read-only.

[WIP] cnispawn: run container in detached transient unit #257

Closed
wants to merge 1 commit into from
Closed
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
4 changes: 4 additions & 0 deletions pkg/cnispawn/netns.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,7 @@ func (c *CniNetns) Set() error {
func (c *CniNetns) Close() error {
return c.netns.Close()
}

func (c *CniNetns) Path() string {
return c.netns.Path()
}
21 changes: 13 additions & 8 deletions pkg/cnispawn/spawn.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package cnispawn

import (
"fmt"
"os"
"os/exec"
"runtime"
Expand All @@ -34,7 +35,6 @@ func Spawn(cniPluginDir string, nspawnArgs []string) error {
if err := cniNetns.Set(); err != nil {
return err
}
defer cniNetns.Close()

systemdNspawnPath := os.Getenv("SYSTEMD_NSPAWN_PATH")

Expand All @@ -45,26 +45,31 @@ func Spawn(cniPluginDir string, nspawnArgs []string) error {
}
}

systemdRunPath, err := exec.LookPath("systemd-run")
if err != nil {
return err
}

args := []string{
systemdRunPath,
"--setenv", "SYSTEMD_NSPAWN_MOUNT_RW=1",
"--setenv", "SYSTEMD_NSPAWN_API_VFS_WRITABLE=1",
"--setenv", "SYSTEMD_NSPAWN_USE_CGNS=0",
"--",
systemdNspawnPath,
"--capability=cap_audit_control,cap_audit_read,cap_audit_write,cap_audit_control,cap_block_suspend,cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_ipc_lock,cap_ipc_owner,cap_kill,cap_lease,cap_linux_immutable,cap_mac_admin,cap_mac_override,cap_mknod,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_setgid,cap_setfcap,cap_setpcap,cap_setuid,cap_sys_admin,cap_sys_boot,cap_sys_chroot,cap_sys_module,cap_sys_nice,cap_sys_pacct,cap_sys_ptrace,cap_sys_rawio,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_syslog,cap_wake_alarm",
"--bind=/sys/fs/cgroup",
"--bind-ro=/boot",
"--bind-ro=/lib/modules",
"--boot",
"--notify-ready=yes",
fmt.Sprintf("--network-namespace-path=%s", cniNetns.Path()),
}

args = append(args, nspawnArgs...)

env := os.Environ()
env = append(env, "SYSTEMD_NSPAWN_MOUNT_RW=1")
env = append(env, "SYSTEMD_NSPAWN_API_VFS_WRITABLE=1")
env = append(env, "SYSTEMD_NSPAWN_USE_CGNS=0")

_, err = syscall.ForkExec(systemdNspawnPath, args, &syscall.ProcAttr{
_, err = syscall.ForkExec(systemdRunPath, args, &syscall.ProcAttr{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use systemd-run --service-type=notify together with systemd-nspawn --notify-ready=yes right now. We could then debug more easily with systemctl status run-xxxx.service.

Possibly use systemd-run --unit= using a user-friendly generated name too. And --slice=machine.slice (I had a look at /usr/lib/systemd/system/systemd-nspawn@.service).

And lastly, but it might require more refactoring so maybe in a future step: instead of syscall.ForkExec(), use os.exec so you can catch the stdout/stderr and exit status, and print those in case of errors. We would need to start the 3 nodes in parallel (in case of a 3-node cluster) and I don't know if the current code does this in parallel (hence the need for refactoring).

Dir: "",
Env: env,
Files: []uintptr{},
Sys: &syscall.SysProcAttr{},
})
Expand Down