docker createHooks

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
")
}
原文地址:https://www.cnblogs.com/dream397/p/14032152.html