play kube: make seccomp handling better conform to k8s
Add flag --seccomp-profile-root in play kube to allow users to specify where to look for seccomp profiles update tests Signed-off-by: Peter Hunt <pehunt@redhat.com>
This commit is contained in:
		
							parent
							
								
									50b4446376
								
							
						
					
					
						commit
						b6792b61de
					
				| 
						 | 
				
			
			@ -314,6 +314,7 @@ type KubePlayValues struct {
 | 
			
		|||
	Quiet              bool
 | 
			
		||||
	SignaturePolicy    string
 | 
			
		||||
	TlsVerify          bool
 | 
			
		||||
	SeccompProfileRoot string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PodCreateValues struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,8 @@ var (
 | 
			
		|||
		},
 | 
			
		||||
		Example: `podman play kube demo.yml`,
 | 
			
		||||
	}
 | 
			
		||||
	// https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
 | 
			
		||||
	defaultSeccompRoot = "/var/lib/kubelet/seccomp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +48,7 @@ func init() {
 | 
			
		|||
		flags.StringVar(&playKubeCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys")
 | 
			
		||||
		flags.StringVar(&playKubeCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)")
 | 
			
		||||
		flags.BoolVar(&playKubeCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries")
 | 
			
		||||
		flags.StringVar(&playKubeCommand.SeccompProfileRoot, "seccomp-profile-root", defaultSeccompRoot, "Directory path for seccomp profiles")
 | 
			
		||||
		markFlagHidden(flags, "signature-policy")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2672,6 +2672,7 @@ _podman_play_kube() {
 | 
			
		|||
    --quiet
 | 
			
		||||
    -q
 | 
			
		||||
    --tls-verify
 | 
			
		||||
    --seccomp-profile-root
 | 
			
		||||
    "
 | 
			
		||||
 | 
			
		||||
    case "$cur" in
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,10 @@ value can be entered.  The password is entered without echo.
 | 
			
		|||
 | 
			
		||||
Suppress output information when pulling images
 | 
			
		||||
 | 
			
		||||
**--seccomp-profile-root**=*path*
 | 
			
		||||
 | 
			
		||||
Directory path for seccomp profiles (default: "/var/lib/kubelet/seccomp"). (Not available for remote commands)
 | 
			
		||||
 | 
			
		||||
**--tls-verify**=*true|false*
 | 
			
		||||
 | 
			
		||||
Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/containers/buildah/pkg/parse"
 | 
			
		||||
| 
						 | 
				
			
			@ -597,7 +598,7 @@ func (r *LocalRuntime) PlayKubeYAML(ctx context.Context, c *cliconfig.KubePlayVa
 | 
			
		|||
		volumes[volume.Name] = hostPath.Path
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	seccompPaths, err := initializeSeccompPaths(podYAML.ObjectMeta.Annotations)
 | 
			
		||||
	seccompPaths, err := initializeSeccompPaths(podYAML.ObjectMeta.Annotations, c.SeccompProfileRoot)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -847,7 +848,8 @@ func (k *kubeSeccompPaths) findForContainer(ctrName string) string {
 | 
			
		|||
 | 
			
		||||
// initializeSeccompPaths takes annotations from the pod object metadata and finds annotations pertaining to seccomp
 | 
			
		||||
// it parses both pod and container level
 | 
			
		||||
func initializeSeccompPaths(annotations map[string]string) (*kubeSeccompPaths, error) {
 | 
			
		||||
// if the annotation is of the form "localhost/%s", the seccomp profile will be set to profileRoot/%s
 | 
			
		||||
func initializeSeccompPaths(annotations map[string]string, profileRoot string) (*kubeSeccompPaths, error) {
 | 
			
		||||
	seccompPaths := &kubeSeccompPaths{containerPaths: make(map[string]string)}
 | 
			
		||||
	var err error
 | 
			
		||||
	if annotations != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -863,7 +865,7 @@ func initializeSeccompPaths(annotations map[string]string) (*kubeSeccompPaths, e
 | 
			
		|||
				return nil, errors.Errorf("Invalid seccomp path: %s", prefixAndCtr[0])
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			path, err := verifySeccompPath(seccomp)
 | 
			
		||||
			path, err := verifySeccompPath(seccomp, profileRoot)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -872,7 +874,7 @@ func initializeSeccompPaths(annotations map[string]string) (*kubeSeccompPaths, e
 | 
			
		|||
 | 
			
		||||
		podSeccomp, ok := annotations[v1.SeccompPodAnnotationKey]
 | 
			
		||||
		if ok {
 | 
			
		||||
			seccompPaths.podPath, err = verifySeccompPath(podSeccomp)
 | 
			
		||||
			seccompPaths.podPath, err = verifySeccompPath(podSeccomp, profileRoot)
 | 
			
		||||
		} else {
 | 
			
		||||
			seccompPaths.podPath, err = libpod.DefaultSeccompPath()
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -885,7 +887,7 @@ func initializeSeccompPaths(annotations map[string]string) (*kubeSeccompPaths, e
 | 
			
		|||
 | 
			
		||||
// verifySeccompPath takes a path and checks whether it is a default, unconfined, or a path
 | 
			
		||||
// the available options are parsed as defined in https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
 | 
			
		||||
func verifySeccompPath(path string) (string, error) {
 | 
			
		||||
func verifySeccompPath(path string, profileRoot string) (string, error) {
 | 
			
		||||
	switch path {
 | 
			
		||||
	case v1.DeprecatedSeccompProfileDockerDefault:
 | 
			
		||||
		fallthrough
 | 
			
		||||
| 
						 | 
				
			
			@ -894,13 +896,9 @@ func verifySeccompPath(path string) (string, error) {
 | 
			
		|||
	case "unconfined":
 | 
			
		||||
		return path, nil
 | 
			
		||||
	default:
 | 
			
		||||
		// TODO we have an inconsistency here
 | 
			
		||||
		// k8s parses `localhost/<path>` which is found at `<seccomp_root>`
 | 
			
		||||
		// we currently parse `localhost:<seccomp_root>/<path>
 | 
			
		||||
		// to fully conform, we need to find a good location for the seccomp root
 | 
			
		||||
		parts := strings.Split(path, ":")
 | 
			
		||||
		parts := strings.Split(path, "/")
 | 
			
		||||
		if parts[0] == "localhost" {
 | 
			
		||||
			return parts[1], nil
 | 
			
		||||
			return filepath.Join(profileRoot, parts[1]), nil
 | 
			
		||||
		}
 | 
			
		||||
		return "", errors.Errorf("invalid seccomp path: %s", path)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -358,10 +358,11 @@ var _ = Describe("Podman generate kube", func() {
 | 
			
		|||
		ctrAnnotation := "container.seccomp.security.alpha.kubernetes.io/" + defaultCtrName
 | 
			
		||||
		ctr := getCtr(withCmd([]string{"pwd"}))
 | 
			
		||||
 | 
			
		||||
		err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation(ctrAnnotation, "localhost:"+jsonFile)), kubeYaml)
 | 
			
		||||
		err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation(ctrAnnotation, "localhost/"+filepath.Base(jsonFile))), kubeYaml)
 | 
			
		||||
		Expect(err).To(BeNil())
 | 
			
		||||
 | 
			
		||||
		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
 | 
			
		||||
		// CreateSeccompJson will put the profile into podmanTest.TempDir. Use --seccomp-profile-root to tell play kube where to look
 | 
			
		||||
		kube := podmanTest.Podman([]string{"play", "kube", "--seccomp-profile-root", podmanTest.TempDir, kubeYaml})
 | 
			
		||||
		kube.WaitWithDefaultTimeout()
 | 
			
		||||
		Expect(kube.ExitCode()).To(Equal(0))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -378,13 +379,15 @@ var _ = Describe("Podman generate kube", func() {
 | 
			
		|||
			fmt.Println(err)
 | 
			
		||||
			Skip("Failed to prepare seccomp.json for test.")
 | 
			
		||||
		}
 | 
			
		||||
		defer os.Remove(jsonFile)
 | 
			
		||||
 | 
			
		||||
		ctr := getCtr(withCmd([]string{"pwd"}))
 | 
			
		||||
 | 
			
		||||
		err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation("seccomp.security.alpha.kubernetes.io/pod", "localhost:"+jsonFile)), kubeYaml)
 | 
			
		||||
		err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation("seccomp.security.alpha.kubernetes.io/pod", "localhost/"+filepath.Base(jsonFile))), kubeYaml)
 | 
			
		||||
		Expect(err).To(BeNil())
 | 
			
		||||
 | 
			
		||||
		kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
 | 
			
		||||
		// CreateSeccompJson will put the profile into podmanTest.TempDir. Use --seccomp-profile-root to tell play kube where to look
 | 
			
		||||
		kube := podmanTest.Podman([]string{"play", "kube", "--seccomp-profile-root", podmanTest.TempDir, kubeYaml})
 | 
			
		||||
		kube.WaitWithDefaultTimeout()
 | 
			
		||||
		Expect(kube.ExitCode()).To(Equal(0))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue