go-nsenter
https://github.com/Devatoria/go-nsenter
package main import ( "fmt" "github.com/Devatoria/go-nsenter" ) func main() { config := &nsenter.Config{ Mount: true, // Execute into mount namespace Target: 1, // Enter into PID 1 (init) namespace } stdout, stderr, err := config.Execute("ls", "-la") if err != nil { fmt.Println(stderr) panic(err) } fmt.Println(stdout) }
func createHooks(rspec *specs.Spec, config *configs.Config) { config.Hooks = &configs.Hooks{} if rspec.Hooks != nil { for _, h := range rspec.Hooks.Prestart { cmd := createCommandHook(h) config.Hooks.Prestart = append(config.Hooks.Prestart, configs.NewCommandHook(cmd)) } for _, h := range rspec.Hooks.Poststart { cmd := createCommandHook(h) config.Hooks.Poststart = append(config.Hooks.Poststart, configs.NewCommandHook(cmd)) } for _, h := range rspec.Hooks.Poststop { cmd := createCommandHook(h) config.Hooks.Poststop = append(config.Hooks.Poststop, configs.NewCommandHook(cmd)) } } }
NewCommandHook will execute the provided command when the hook is run. func NewCommandHook(cmd Command) CommandHook { return CommandHook{ Command: cmd, } }
type Command struct { Path string `json:"path"` Args []string `json:"args"` Env []string `json:"env"` Dir string `json:"dir"` Timeout *time.Duration `json:"timeout"` } // NewCommandHook will execute the provided command when the hook is run. func NewCommandHook(cmd Command) CommandHook { return CommandHook{ Command: cmd, } } type CommandHook struct {
# cat /var/lib/docker/hooks/hookspec.json { "prestart": [ { "path": "/var/lib/docker/hooks/lxcfs-hook", "args": ["lxcfs-hook", "--log", "/var/log/lxcfs-hook.log"], "env": [] } ], "poststart":[], "poststop":[] }
https://gitlab.com/container-manager/nvidia-container-runtime-hook/-/blob/master/hook/nvidia-container-runtime-hook/main.go
// getRootfsPath returns an absolute path. We don't need to resolve symlinks for now. func getRootfsPath(config containerConfig) string { rootfs, err := filepath.Abs(config.Rootfs) if err != nil { log.Panicln(err) } return rootfs } func doPrestart() { var err error defer exit() log.SetFlags(0) hook := getHookConfig() cli := hook.NvidiaContainerCLI container := getContainerConfig(hook) rootfs := getRootfsPath(container) nsConfig := &nsenter.Config{ Mount: true, Target: container.Pid, } certPath := path.Join(rootfs, "/.ca-certificates.crt") cmd := fmt.Sprintf(`bash -c " touch %s mount -o bind,ro /etc/ssl/certs/ca-certificates.crt %s "`, certPath, certPath) nsConfig.Execute("bash", "-c", cmd) nvidia := container.Nvidia if nvidia == nil { // Not a GPU container, nothing to do. return } args := []string{getCLIPath(cli)} if cli.Root != nil { args = append(args, fmt.Sprintf("--root=%s", *cli.Root)) } if cli.LoadKmods { args = append(args, "--load-kmods") } if *debugflag { args = append(args, "--debug=/dev/stderr") } else if cli.Debug != nil { args = append(args, fmt.Sprintf("--debug=%s", *cli.Debug)) } if cli.Ldcache != nil { args = append(args, fmt.Sprintf("--ldcache=%s", *cli.Ldcache)) } if cli.User != nil { args = append(args, fmt.Sprintf("--user=%s", *cli.User)) } args = append(args, "configure") if cli.Ldconfig != nil { args = append(args, fmt.Sprintf("--ldconfig=%s", *cli.Ldconfig)) } if cli.NoCgroups { args = append(args, "--no-cgroups") } if len(nvidia.Devices) > 0 { args = append(args, fmt.Sprintf("--device=%s", nvidia.Devices)) } for _, cap := range strings.Split(nvidia.Capabilities, ",") { if len(cap) == 0 { break } args = append(args, capabilityToCLI(cap)) } if !hook.DisableRequire && !nvidia.DisableRequire { for _, req := range nvidia.Requirements { args = append(args, fmt.Sprintf("--require=%s", req)) } } args = append(args, fmt.Sprintf("--pid=%s", strconv.FormatUint(uint64(container.Pid), 10))) args = append(args, rootfs) log.Printf("exec command: %v", args) env := append(os.Environ(), cli.Environment...) err = syscall.Exec(args[0], args, env) log.Panicln("exec failed:", err) } func usage() { fmt.Fprintf(os.Stderr, "Usage of %s: ", os.Args[0]) flag.PrintDefaults() fmt.Fprintf(os.Stderr, " Commands: ") fmt.Fprintf(os.Stderr, " prestart run the prestart hook ") fmt.Fprintf(os.Stderr, " poststart no-op ") fmt.Fprintf(os.Stderr, " poststop no-op ") }