Add support for oci-hooks to libkpod
Add new directory /etc/crio/hooks.d, where packagers can drop a json config file to specify a hook. The json must specify a valid executable to run. The json must also specify which stage(s) to run the hook: prestart, poststart, poststop The json must specify under which criteria the hook should be launched If the container HasBindMounts If the container cmd matches a list of regular expressions If the containers annotations matches a list of regular expressions. If any of these match the the hook will be launched. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
8538c4067a
commit
139d0841e8
13 changed files with 365 additions and 1 deletions
|
@ -7,6 +7,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -198,6 +199,24 @@ func buildOCIProcessArgs(containerKubeConfig *pb.ContainerConfig, imageOCIConfig
|
|||
return processArgs, nil
|
||||
}
|
||||
|
||||
// addOCIHook look for hooks programs installed in hooksDirPath and add them to spec
|
||||
func addOCIHook(specgen *generate.Generator, hook libkpod.HookParams) error {
|
||||
logrus.Debugf("AddOCIHook", hook)
|
||||
for _, stage := range hook.Stage {
|
||||
switch stage {
|
||||
case "prestart":
|
||||
specgen.AddPreStartHook(hook.Hook, []string{hook.Hook, "prestart"})
|
||||
|
||||
case "poststart":
|
||||
specgen.AddPostStartHook(hook.Hook, []string{hook.Hook, "poststart"})
|
||||
|
||||
case "poststop":
|
||||
specgen.AddPostStopHook(hook.Hook, []string{hook.Hook, "poststop"})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setupContainerUser sets the UID, GID and supplemental groups in OCI runtime config
|
||||
func setupContainerUser(specgen *generate.Generator, rootfs string, sc *pb.LinuxContainerSecurityContext, imageConfig *v1.Image) error {
|
||||
if sc != nil {
|
||||
|
@ -355,6 +374,56 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *Server) setupOCIHooks(specgen *generate.Generator, sb *sandbox.Sandbox, containerConfig *pb.ContainerConfig, command string) error {
|
||||
mounts := containerConfig.GetMounts()
|
||||
addedHooks := map[string]struct{}{}
|
||||
addHook := func(hook libkpod.HookParams) error {
|
||||
// Only add a hook once
|
||||
if _, ok := addedHooks[hook.Hook]; !ok {
|
||||
if err := addOCIHook(specgen, hook); err != nil {
|
||||
return err
|
||||
}
|
||||
addedHooks[hook.Hook] = struct{}{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for _, hook := range s.Hooks() {
|
||||
logrus.Debugf("SetupOCIHooks", hook)
|
||||
if hook.HasBindMounts && len(mounts) > 0 {
|
||||
if err := addHook(hook); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, cmd := range hook.Cmds {
|
||||
match, err := regexp.MatchString(cmd, command)
|
||||
if err != nil {
|
||||
logrus.Errorf("Invalid regex %q:%q", cmd, err)
|
||||
continue
|
||||
}
|
||||
if match {
|
||||
if err := addHook(hook); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, annotationRegex := range hook.Annotations {
|
||||
for _, annotation := range sb.Annotations() {
|
||||
match, err := regexp.MatchString(annotationRegex, annotation)
|
||||
if err != nil {
|
||||
logrus.Errorf("Invalid regex %q:%q", annotationRegex, err)
|
||||
continue
|
||||
}
|
||||
if match {
|
||||
if err := addHook(hook); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s *Server) createSandboxContainer(ctx context.Context, containerID string, containerName string, sb *sandbox.Sandbox, SandboxConfig *pb.PodSandboxConfig, containerConfig *pb.ContainerConfig) (*oci.Container, error) {
|
||||
if sb == nil {
|
||||
return nil, errors.New("createSandboxContainer needs a sandbox")
|
||||
|
@ -762,6 +831,10 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string,
|
|||
}
|
||||
specgen.SetProcessCwd(containerCwd)
|
||||
|
||||
if err := s.setupOCIHooks(&specgen, sb, containerConfig, processArgs[0]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Setup user and groups
|
||||
if linux != nil {
|
||||
if err = setupContainerUser(&specgen, mountPoint, linux.GetSecurityContext(), containerImageConfig); err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue