Add support for container kernel capabilities (#716)
This patch adds two new command-line flags to specify one or more kernel capabilities to add or remove from the workflow containers. The command-line flag `--container-cap-add` allows for adding specific capabilities on the workflow containers; where as, The command-line flag `--container-cap-drop` allows for removing specific capabilities on the workflow containers. This was developed to specifically be able to add `SYS_PTRACE` to a workflow I maintain. It involves using this capability to monitor a make build, to then build a compilation database. Signed-off-by: Joseph Benden <joe@benden.us>
This commit is contained in:
parent
8a9167da82
commit
6b4d359737
6 changed files with 17 additions and 7 deletions
|
@ -32,6 +32,8 @@ type Input struct {
|
||||||
noWorkflowRecurse bool
|
noWorkflowRecurse bool
|
||||||
useGitIgnore bool
|
useGitIgnore bool
|
||||||
githubInstance string
|
githubInstance string
|
||||||
|
containerCapAdd []string
|
||||||
|
containerCapDrop []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) resolve(path string) string {
|
func (i *Input) resolve(path string) string {
|
||||||
|
|
|
@ -50,6 +50,8 @@ func Execute(ctx context.Context, version string) {
|
||||||
rootCmd.Flags().BoolVar(&input.privileged, "privileged", false, "use privileged mode")
|
rootCmd.Flags().BoolVar(&input.privileged, "privileged", false, "use privileged mode")
|
||||||
rootCmd.Flags().StringVar(&input.usernsMode, "userns", "", "user namespace to use")
|
rootCmd.Flags().StringVar(&input.usernsMode, "userns", "", "user namespace to use")
|
||||||
rootCmd.Flags().BoolVar(&input.useGitIgnore, "use-gitignore", true, "Controls whether paths specified in .gitignore should be copied into container")
|
rootCmd.Flags().BoolVar(&input.useGitIgnore, "use-gitignore", true, "Controls whether paths specified in .gitignore should be copied into container")
|
||||||
|
rootCmd.Flags().StringArrayVarP(&input.containerCapAdd, "container-cap-add", "", []string{}, "kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)")
|
||||||
|
rootCmd.Flags().StringArrayVarP(&input.containerCapDrop, "container-cap-drop", "", []string{}, "kernel capabilities to remove from the workflow containers (e.g. --container-cap-drop SYS_PTRACE)")
|
||||||
rootCmd.PersistentFlags().StringVarP(&input.actor, "actor", "a", "nektos/act", "user that triggered the event")
|
rootCmd.PersistentFlags().StringVarP(&input.actor, "actor", "a", "nektos/act", "user that triggered the event")
|
||||||
rootCmd.PersistentFlags().StringVarP(&input.workflowsPath, "workflows", "W", "./.github/workflows/", "path to workflow file(s)")
|
rootCmd.PersistentFlags().StringVarP(&input.workflowsPath, "workflows", "W", "./.github/workflows/", "path to workflow file(s)")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&input.noWorkflowRecurse, "no-recurse", "", false, "Flag to disable running workflows from subdirectories of specified path in '--workflows'/'-W' flag")
|
rootCmd.PersistentFlags().BoolVarP(&input.noWorkflowRecurse, "no-recurse", "", false, "Flag to disable running workflows from subdirectories of specified path in '--workflows'/'-W' flag")
|
||||||
|
@ -259,6 +261,8 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
ContainerDaemonSocket: input.containerDaemonSocket,
|
ContainerDaemonSocket: input.containerDaemonSocket,
|
||||||
UseGitIgnore: input.useGitIgnore,
|
UseGitIgnore: input.useGitIgnore,
|
||||||
GitHubInstance: input.githubInstance,
|
GitHubInstance: input.githubInstance,
|
||||||
|
ContainerCapAdd: input.containerCapAdd,
|
||||||
|
ContainerCapDrop: input.containerCapDrop,
|
||||||
}
|
}
|
||||||
r, err := runner.New(config)
|
r, err := runner.New(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -63,7 +63,7 @@ type FileEntry struct {
|
||||||
|
|
||||||
// Container for managing docker run containers
|
// Container for managing docker run containers
|
||||||
type Container interface {
|
type Container interface {
|
||||||
Create() common.Executor
|
Create(capAdd []string, capDrop []string) common.Executor
|
||||||
Copy(destPath string, files ...*FileEntry) common.Executor
|
Copy(destPath string, files ...*FileEntry) common.Executor
|
||||||
CopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor
|
CopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor
|
||||||
Pull(forcePull bool) common.Executor
|
Pull(forcePull bool) common.Executor
|
||||||
|
@ -100,14 +100,14 @@ func supportsContainerImagePlatform(cli *client.Client) bool {
|
||||||
return constraint.Check(sv)
|
return constraint.Check(sv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *containerReference) Create() common.Executor {
|
func (cr *containerReference) Create(capAdd []string, capDrop []string) common.Executor {
|
||||||
return common.
|
return common.
|
||||||
NewDebugExecutor("%sdocker create image=%s platform=%s entrypoint=%+q cmd=%+q", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd).
|
NewDebugExecutor("%sdocker create image=%s platform=%s entrypoint=%+q cmd=%+q", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd).
|
||||||
Then(
|
Then(
|
||||||
common.NewPipelineExecutor(
|
common.NewPipelineExecutor(
|
||||||
cr.connect(),
|
cr.connect(),
|
||||||
cr.find(),
|
cr.find(),
|
||||||
cr.create(),
|
cr.create(capAdd, capDrop),
|
||||||
).IfNot(common.Dryrun),
|
).IfNot(common.Dryrun),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ func (cr *containerReference) remove() common.Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *containerReference) create() common.Executor {
|
func (cr *containerReference) create(capAdd []string, capDrop []string) common.Executor {
|
||||||
return func(ctx context.Context) error {
|
return func(ctx context.Context) error {
|
||||||
if cr.id != "" {
|
if cr.id != "" {
|
||||||
return nil
|
return nil
|
||||||
|
@ -315,6 +315,8 @@ func (cr *containerReference) create() common.Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp, err := cr.cli.ContainerCreate(ctx, config, &container.HostConfig{
|
resp, err := cr.cli.ContainerCreate(ctx, config, &container.HostConfig{
|
||||||
|
CapAdd: capAdd,
|
||||||
|
CapDrop: capDrop,
|
||||||
Binds: input.Binds,
|
Binds: input.Binds,
|
||||||
Mounts: mounts,
|
Mounts: mounts,
|
||||||
NetworkMode: container.NetworkMode(input.NetworkMode),
|
NetworkMode: container.NetworkMode(input.NetworkMode),
|
||||||
|
|
|
@ -148,7 +148,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
||||||
return common.NewPipelineExecutor(
|
return common.NewPipelineExecutor(
|
||||||
rc.JobContainer.Pull(rc.Config.ForcePull),
|
rc.JobContainer.Pull(rc.Config.ForcePull),
|
||||||
rc.stopJobContainer(),
|
rc.stopJobContainer(),
|
||||||
rc.JobContainer.Create(),
|
rc.JobContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),
|
||||||
rc.JobContainer.Start(false),
|
rc.JobContainer.Start(false),
|
||||||
rc.JobContainer.UpdateFromEnv("/etc/environment", &rc.Env),
|
rc.JobContainer.UpdateFromEnv("/etc/environment", &rc.Env),
|
||||||
rc.JobContainer.Exec([]string{"mkdir", "-m", "0777", "-p", ActPath}, rc.Env, "root"),
|
rc.JobContainer.Exec([]string{"mkdir", "-m", "0777", "-p", ActPath}, rc.Env, "root"),
|
||||||
|
|
|
@ -40,6 +40,8 @@ type Config struct {
|
||||||
ContainerDaemonSocket string // Path to Docker daemon socket
|
ContainerDaemonSocket string // Path to Docker daemon socket
|
||||||
UseGitIgnore bool // controls if paths in .gitignore should not be copied into container, default true
|
UseGitIgnore bool // controls if paths in .gitignore should not be copied into container, default true
|
||||||
GitHubInstance string // GitHub instance to use, default "github.com"
|
GitHubInstance string // GitHub instance to use, default "github.com"
|
||||||
|
ContainerCapAdd []string // list of kernel capabilities to add to the containers
|
||||||
|
ContainerCapDrop []string // list of kernel capabilities to remove from the containers
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolves the equivalent host path inside the container
|
// Resolves the equivalent host path inside the container
|
||||||
|
|
|
@ -299,7 +299,7 @@ func (sc *StepContext) runUsesContainer() common.Executor {
|
||||||
return common.NewPipelineExecutor(
|
return common.NewPipelineExecutor(
|
||||||
stepContainer.Pull(rc.Config.ForcePull),
|
stepContainer.Pull(rc.Config.ForcePull),
|
||||||
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
||||||
stepContainer.Create(),
|
stepContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),
|
||||||
stepContainer.Start(true),
|
stepContainer.Start(true),
|
||||||
).Finally(
|
).Finally(
|
||||||
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
||||||
|
@ -517,7 +517,7 @@ func (sc *StepContext) execAsDocker(ctx context.Context, action *model.Action, a
|
||||||
prepImage,
|
prepImage,
|
||||||
stepContainer.Pull(rc.Config.ForcePull),
|
stepContainer.Pull(rc.Config.ForcePull),
|
||||||
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
||||||
stepContainer.Create(),
|
stepContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),
|
||||||
stepContainer.Start(true),
|
stepContainer.Start(true),
|
||||||
).Finally(
|
).Finally(
|
||||||
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
stepContainer.Remove().IfBool(!rc.Config.ReuseContainers),
|
||||||
|
|
Loading…
Reference in a new issue