Skip to content

pkg/hooks: Version the hook structure and add 1.0.0 hooks #686

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits 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
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ The plan is to use OCI projects and best of breed libraries for different aspect
**[Installation notes](/install.md)**
Information on how to install Podman in your environment.

**[OCI Hooks Support](/hooks.md)**
Information on how Podman configures OCI Hooks to run when launching a container.
**[OCI Hooks Support](pkg/hooks/README.md)**
Information on how Podman configures [OCI Hooks][spec-hooks] to run when launching a container.

**[Podman Commands](/commands.md)**
A list of the Podman commands with links to their man pages and in many cases videos
Expand All @@ -64,3 +64,5 @@ Information about contributing to this project.
1. Pod commands for Podman
1. Rootless containers
1. Support for cleaning up containers via post-run hooks

[spec-hooks]: https://github.com/opencontainers/runtime-spec/blob/v1.0.1/config.md#posix-platform-hooks
2 changes: 1 addition & 1 deletion cmd/podman/libpodruntime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions
if c.GlobalIsSet("default-mounts-file") {
options = append(options, libpod.WithDefaultMountsFile(c.GlobalString("default-mounts-file")))
}
options = append(options, libpod.WithHooksDir(c.GlobalString("hooks-dir-path")))
options = append(options, libpod.WithHooksDir(c.GlobalString("hooks-dir-path"), c.GlobalIsSet("hooks-dir-path")))

// TODO flag to set CNI plugins dir?

Expand Down
3 changes: 2 additions & 1 deletion cmd/podman/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/containers/storage/pkg/reexec"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/pkg/hooks"
_ "github.com/projectatomic/libpod/pkg/hooks/0.1.0"
"github.com/projectatomic/libpod/version"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
Expand Down Expand Up @@ -136,7 +137,7 @@ func main() {
cli.StringFlag{
Name: "hooks-dir-path",
Usage: "set the OCI hooks directory path",
Value: hooks.DefaultHooksDir,
Value: hooks.DefaultDir,
Hidden: true,
},
cli.StringFlag{
Expand Down
91 changes: 0 additions & 91 deletions hooks.md

This file was deleted.

97 changes: 47 additions & 50 deletions libpod/container_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"strings"
"syscall"
"time"
Expand All @@ -33,13 +32,23 @@ import (
"github.com/sirupsen/logrus"
"github.com/ulule/deepcopier"
"golang.org/x/sys/unix"
"golang.org/x/text/language"
)

const (
// name of the directory holding the artifacts
artifactsDir = "artifacts"
)

var (
// localeToLanguage maps from locale values to language tags.
localeToLanguage = map[string]string{
"": "und-u-va-posix",
"c": "und-u-va-posix",
"posix": "und-u-va-posix",
}
)

// rootFsSize gets the size of the container's root filesystem
// A container FS is split into two parts. The first is the top layer, a
// mutable layer, and the rest is the RootFS: the set of immutable layers
Expand Down Expand Up @@ -1064,7 +1073,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}

if err := c.setupOCIHooks(&g); err != nil {
if err := c.setupOCIHooks(ctx, &g); err != nil {
return nil, errors.Wrapf(err, "error setting up OCI Hooks")
}
// Bind builtin image volumes
Expand Down Expand Up @@ -1283,58 +1292,46 @@ func (c *Container) saveSpec(spec *spec.Spec) error {
return nil
}

// Add OCI hooks to a container's spec
func (c *Container) setupOCIHooks(g *generate.Generator) error {
addedHooks := map[string]struct{}{}
ocihooks, err := hooks.SetupHooks(c.runtime.config.HooksDir)
if err != nil {
return err
}
addHook := func(hook hooks.HookParams) error {
// Only add a hook once
if _, ok := addedHooks[hook.Hook]; !ok {
if err := hooks.AddOCIHook(g, hook); err != nil {
return err
}
addedHooks[hook.Hook] = struct{}{}
}
func (c *Container) setupOCIHooks(ctx context.Context, g *generate.Generator) error {
if c.runtime.config.HooksDir == "" {
return nil
}
for _, hook := range ocihooks {
logrus.Debugf("SetupOCIHooks", hook)
if hook.HasBindMounts && len(c.config.UserVolumes) > 0 {
if err := addHook(hook); err != nil {
return err
}
continue

var locale string
var ok bool
for _, envVar := range []string{
"LC_ALL",
"LC_COLLATE",
"LANG",
} {
locale, ok = os.LookupEnv(envVar)
if ok {
break
}
for _, cmd := range hook.Cmds {
match, err := regexp.MatchString(cmd, c.config.Spec.Process.Args[0])
if err != nil {
logrus.Errorf("Invalid regex %q:%q", cmd, err)
continue
}
if match {
if err := addHook(hook); err != nil {
return err
}
}
}

langString, ok := localeToLanguage[strings.ToLower(locale)]
if !ok {
langString = locale
}

lang, err := language.Parse(langString)
if err != nil {
logrus.Warnf("failed to parse language %q: %s", langString, err)
lang, err = language.Parse("und-u-va-posix")
if err != nil {
return err
}
annotations := c.Spec().Annotations
for _, annotationRegex := range hook.Annotations {
for _, annotation := range 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
}
}
}
}

manager, err := hooks.New(ctx, []string{c.runtime.config.HooksDir}, lang)
if err != nil {
if c.runtime.config.HooksDirNotExistFatal || !os.IsNotExist(err) {
return err
}
logrus.Warnf("failed to load hooks: {}", err)
return nil
}
return nil

return manager.Hooks(g.Spec(), c.Spec().Annotations, len(c.config.UserVolumes) > 0)
}
7 changes: 6 additions & 1 deletion libpod/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,18 @@ func WithStaticDir(dir string) RuntimeOption {
// WithHooksDir sets the directory to look for OCI runtime hooks config.
// Note we are not saving this in database, since this is really just for used
// for testing.
func WithHooksDir(hooksDir string) RuntimeOption {
func WithHooksDir(hooksDir string, dirNotExistFatal bool) RuntimeOption {
return func(rt *Runtime) error {
if rt.valid {
return ErrRuntimeFinalized
}

if hooksDir == "" {
return errors.Wrap(ErrInvalidArg, "empty-string hook directories are not supported")
}

rt.config.HooksDir = hooksDir
rt.config.HooksDirNotExistFatal = dirNotExistFatal
return nil
}
}
Expand Down
4 changes: 3 additions & 1 deletion libpod/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ type RuntimeConfig struct {
CNIPluginDir []string `toml:"cni_plugin_dir"`
// HooksDir Path to the directory containing hooks configuration files
HooksDir string `toml:"hooks_dir"`
// HooksDirNotExistFatal switches between fatal errors and non-fatal warnings if the configured HooksDir does not exist.
HooksDirNotExistFatal bool `toml:"hooks_dir_not_exist_fatal"`
// DefaultMountsFile is the path to the default mounts file for testing purposes only
DefaultMountsFile string `toml:"-"`
}
Expand Down Expand Up @@ -159,7 +161,7 @@ var (
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
},
CgroupManager: CgroupfsCgroupsManager,
HooksDir: hooks.DefaultHooksDir,
HooksDir: hooks.DefaultDir,
StaticDir: filepath.Join(storage.DefaultStoreOptions.GraphRoot, "libpod"),
TmpDir: "/var/run/libpod",
MaxLogSize: -1,
Expand Down
Loading