diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/adapter/containers.go | 24 | ||||
-rw-r--r-- | pkg/adapter/containers_remote.go | 6 | ||||
-rw-r--r-- | pkg/adapter/pods.go | 102 | ||||
-rw-r--r-- | pkg/adapter/pods_remote.go | 2 | ||||
-rw-r--r-- | pkg/adapter/runtime_remote.go | 2 | ||||
-rw-r--r-- | pkg/hooks/docs/oci-hooks.5.md | 2 | ||||
-rw-r--r-- | pkg/spec/storage.go | 10 | ||||
-rw-r--r-- | pkg/trust/trust.go | 2 | ||||
-rw-r--r-- | pkg/util/utils.go | 2 |
9 files changed, 129 insertions, 23 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 287bd8474..02da9ec8c 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -79,7 +79,17 @@ func (r *LocalRuntime) StopContainers(ctx context.Context, cli *cliconfig.StopVa } logrus.Debugf("Setting maximum stop workers to %d", maxWorkers) - ctrs, err := shortcuts.GetContainersByContext(cli.All, cli.Latest, cli.InputArgs, r.Runtime) + names := cli.InputArgs + for _, cidFile := range cli.CIDFiles { + content, err := ioutil.ReadFile(cidFile) + if err != nil { + return nil, nil, errors.Wrap(err, "error reading CIDFile") + } + id := strings.Split(string(content), "\n")[0] + names = append(names, id) + } + + ctrs, err := shortcuts.GetContainersByContext(cli.All, cli.Latest, names, r.Runtime) if err != nil { return nil, nil, err } @@ -203,7 +213,17 @@ func (r *LocalRuntime) RemoveContainers(ctx context.Context, cli *cliconfig.RmVa return ok, failures, nil } - ctrs, err := shortcuts.GetContainersByContext(cli.All, cli.Latest, cli.InputArgs, r.Runtime) + names := cli.InputArgs + for _, cidFile := range cli.CIDFiles { + content, err := ioutil.ReadFile(cidFile) + if err != nil { + return nil, nil, errors.Wrap(err, "error reading CIDFile") + } + id := strings.Split(string(content), "\n")[0] + names = append(names, id) + } + + ctrs, err := shortcuts.GetContainersByContext(cli.All, cli.Latest, names, r.Runtime) if err != nil { // Failed to get containers. If force is specified, get the containers ID // and evict them diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go index 20471d895..e34b8ffd9 100644 --- a/pkg/adapter/containers_remote.go +++ b/pkg/adapter/containers_remote.go @@ -178,7 +178,7 @@ func (r *LocalRuntime) LookupContainersWithStatus(filters []string) ([]*Containe if err != nil { return nil, err } - // This is not performance savy; if this turns out to be a problematic series of lookups, we need to + // This is not performance savvy; if this turns out to be a problematic series of lookups, we need to // create a new endpoint to speed things up for _, ctr := range ctrs { container, err := r.LookupContainer(ctr.Id) @@ -617,7 +617,7 @@ func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues) error { return err } if c.All { - // We dont have a great way to get all the running containers, so need to get all and then + // We don't have a great way to get all the running containers, so need to get all and then // check status on them bc checkpoint considers checkpointing a stopped container an error var runningIds []string for _, id := range ids { @@ -660,7 +660,7 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues) return err } if c.All { - // We dont have a great way to get all the exited containers, so need to get all and then + // We don't have a great way to get all the exited containers, so need to get all and then // check status on them bc checkpoint considers restoring a running container an error var exitedIDs []string for _, id := range ids { diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go index 85f93ed3e..d73a8b21b 100644 --- a/pkg/adapter/pods.go +++ b/pkg/adapter/pods.go @@ -17,6 +17,7 @@ import ( "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/adapter/shortcuts" + ann "github.com/containers/libpod/pkg/annotations" ns "github.com/containers/libpod/pkg/namespaces" createconfig "github.com/containers/libpod/pkg/spec" "github.com/containers/libpod/pkg/util" @@ -36,7 +37,7 @@ const ( ) // PodContainerStats is struct containing an adapter Pod and a libpod -// ContainerStats and is used primarily for outputing pod stats. +// ContainerStats and is used primarily for outputting pod stats. type PodContainerStats struct { Pod *Pod ContainerStats map[string]*libpod.ContainerStats @@ -595,12 +596,17 @@ func (r *LocalRuntime) PlayKubeYAML(ctx context.Context, c *cliconfig.KubePlayVa volumes[volume.Name] = hostPath.Path } + seccompPaths, err := initializeSeccompPaths(podYAML.ObjectMeta.Annotations) + if err != nil { + return nil, err + } + for _, container := range podYAML.Spec.Containers { newImage, err := r.ImageRuntime().New(ctx, container.Image, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, nil, util.PullImageMissing) if err != nil { return nil, err } - createConfig, err := kubeContainerToCreateConfig(ctx, container, r.Runtime, newImage, namespaces, volumes, pod.ID()) + createConfig, err := kubeContainerToCreateConfig(ctx, container, r.Runtime, newImage, namespaces, volumes, pod.ID(), podInfraID, seccompPaths) if err != nil { return nil, err } @@ -719,7 +725,7 @@ func setupSecurityContext(securityConfig *createconfig.SecurityConfig, userConfi } // kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container -func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string, podID string) (*createconfig.CreateConfig, error) { +func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string, podID, infraID string, seccompPaths *kubeSeccompPaths) (*createconfig.CreateConfig, error) { var ( containerConfig createconfig.CreateConfig pidConfig createconfig.PidConfig @@ -751,11 +757,7 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container setupSecurityContext(&securityConfig, &userConfig, containerYAML) - var err error - containerConfig.Security.SeccompProfilePath, err = libpod.DefaultSeccompPath() - if err != nil { - return nil, err - } + securityConfig.SeccompProfilePath = seccompPaths.findForContainer(containerConfig.Name) containerConfig.Command = []string{} if imageData != nil && imageData.Config != nil { @@ -800,6 +802,13 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container // Set default environment variables and incorporate data from image, if necessary envs := shared.EnvVariablesFromData(imageData) + annotations := make(map[string]string) + if infraID != "" { + annotations[ann.SandboxID] = infraID + annotations[ann.ContainerType] = ann.ContainerTypeContainer + } + containerConfig.Annotations = annotations + // Environment Variables for _, e := range containerYAML.Env { envs[e.Name] = e.Value @@ -818,3 +827,80 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container } return &containerConfig, nil } + +// kubeSeccompPaths holds information about a pod YAML's seccomp configuration +// it holds both container and pod seccomp paths +type kubeSeccompPaths struct { + containerPaths map[string]string + podPath string +} + +// findForContainer checks whether a container has a seccomp path configured for it +// if not, it returns the podPath, which should always have a value +func (k *kubeSeccompPaths) findForContainer(ctrName string) string { + if path, ok := k.containerPaths[ctrName]; ok { + return path + } + return k.podPath +} + +// 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) { + seccompPaths := &kubeSeccompPaths{containerPaths: make(map[string]string)} + var err error + if annotations != nil { + for annKeyValue, seccomp := range annotations { + // check if it is prefaced with container.seccomp.security.alpha.kubernetes.io/ + prefixAndCtr := strings.Split(annKeyValue, "/") + if prefixAndCtr[0]+"/" != v1.SeccompContainerAnnotationKeyPrefix { + continue + } else if len(prefixAndCtr) != 2 { + // this could be caused by a user inputting either of + // container.seccomp.security.alpha.kubernetes.io{,/} + // both of which are invalid + return nil, errors.Errorf("Invalid seccomp path: %s", prefixAndCtr[0]) + } + + path, err := verifySeccompPath(seccomp) + if err != nil { + return nil, err + } + seccompPaths.containerPaths[prefixAndCtr[1]] = path + } + + podSeccomp, ok := annotations[v1.SeccompPodAnnotationKey] + if ok { + seccompPaths.podPath, err = verifySeccompPath(podSeccomp) + } else { + seccompPaths.podPath, err = libpod.DefaultSeccompPath() + } + if err != nil { + return nil, err + } + } + return seccompPaths, nil +} + +// 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) { + switch path { + case v1.DeprecatedSeccompProfileDockerDefault: + fallthrough + case v1.SeccompProfileRuntimeDefault: + return libpod.DefaultSeccompPath() + 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, ":") + if parts[0] == "localhost" { + return parts[1], nil + } + return "", errors.Errorf("invalid seccomp path: %s", path) + } +} diff --git a/pkg/adapter/pods_remote.go b/pkg/adapter/pods_remote.go index 0c62ac923..16d34769e 100644 --- a/pkg/adapter/pods_remote.go +++ b/pkg/adapter/pods_remote.go @@ -19,7 +19,7 @@ import ( ) // PodContainerStats is struct containing an adapter Pod and a libpod -// ContainerStats and is used primarily for outputing pod stats. +// ContainerStats and is used primarily for outputting pod stats. type PodContainerStats struct { Pod *Pod ContainerStats map[string]*libpod.ContainerStats diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index 32eb934bf..ddd4b5271 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -450,7 +450,7 @@ func (r *LocalRuntime) GetFileFromRemoteHost(remoteFilePath, outputPath string, reader := r.Conn.Reader if _, err := io.CopyN(writer, reader, length); err != nil { - return errors.Wrap(err, "file transer failed") + return errors.Wrap(err, "file transfer failed") } return nil } diff --git a/pkg/hooks/docs/oci-hooks.5.md b/pkg/hooks/docs/oci-hooks.5.md index 0a01e1bb8..b50a6bddc 100644 --- a/pkg/hooks/docs/oci-hooks.5.md +++ b/pkg/hooks/docs/oci-hooks.5.md @@ -21,7 +21,7 @@ The default directory is `/usr/share/containers/oci/hooks.d`, but tools consumin If multiple directories are configured, a JSON filename in a preferred directory masks entries with the same filename in directories with lower precedence. For example, if a consuming tool watches for hooks in `/etc/containers/oci/hooks.d` and `/usr/share/containers/oci/hooks.d` (in order of decreasing precedence), then a hook definition in `/etc/containers/oci/hooks.d/01-my-hook.json` will mask any definition in `/usr/share/containers/oci/hooks.d/01-my-hook.json`. -Tools consuming this format may also opt to monitor the hook directries for changes, in which case they will notice additions, changes, and removals to JSON files without needing to be restarted or otherwise signaled. When the tool monitors multiple hooks directories, the precedence discussed in the previous paragraph still applies. For example, if a consuming tool watches for hooks in `/etc/containers/oci/hooks.d` and `/usr/share/containers/oci/hooks.d` (in order of decreasing precedence), then writing a new hook definition to `/etc/containers/oci/hooks.d/01-my-hook.json` will mask the hook previously loaded from `/usr/share/containers/oci/hooks.d/01-my-hook.json`. Subsequent changes to `/usr/share/containers/oci/hooks.d/01-my-hook.json` will have no effect on the consuming tool as long as `/etc/containers/oci/hooks.d/01-my-hook.json` exists. Removing `/etc/containers/oci/hooks.d/01-my-hook.json` will reload the hook from `/usr/share/containers/oci/hooks.d/01-my-hook.json`. +Tools consuming this format may also opt to monitor the hook directories for changes, in which case they will notice additions, changes, and removals to JSON files without needing to be restarted or otherwise signaled. When the tool monitors multiple hooks directories, the precedence discussed in the previous paragraph still applies. For example, if a consuming tool watches for hooks in `/etc/containers/oci/hooks.d` and `/usr/share/containers/oci/hooks.d` (in order of decreasing precedence), then writing a new hook definition to `/etc/containers/oci/hooks.d/01-my-hook.json` will mask the hook previously loaded from `/usr/share/containers/oci/hooks.d/01-my-hook.json`. Subsequent changes to `/usr/share/containers/oci/hooks.d/01-my-hook.json` will have no effect on the consuming tool as long as `/etc/containers/oci/hooks.d/01-my-hook.json` exists. Removing `/etc/containers/oci/hooks.d/01-my-hook.json` will reload the hook from `/usr/share/containers/oci/hooks.d/01-my-hook.json`. Hooks are injected in the order obtained by sorting the JSON file names, after converting them to lower case, based on their Unicode code points. For example, a matching hook defined in `01-my-hook.json` would be injected before matching hooks defined in `02-another-hook.json` and `01-UPPERCASE.json`. diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index 79c065b5d..dbdab0030 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -136,9 +136,9 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount, unifiedMounts[initMount.Destination] = initMount } - // Before superceding, we need to find volume mounts which conflict with + // Before superseding, we need to find volume mounts which conflict with // named volumes, and vice versa. - // We'll delete the conflicts here as we supercede. + // We'll delete the conflicts here as we supersede. for dest := range unifiedMounts { if _, ok := baseVolumes[dest]; ok { delete(baseVolumes, dest) @@ -150,7 +150,7 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount, } } - // Supercede volumes-from/image volumes with unified volumes from above. + // Supersede volumes-from/image volumes with unified volumes from above. // This is an unconditional replacement. for dest, mount := range unifiedMounts { baseMounts[dest] = mount @@ -336,7 +336,7 @@ func (config *CreateConfig) getMounts() (map[string]spec.Mount, map[string]*libp // TODO(vrothberg): the manual parsing can be replaced with a regular expression // to allow a more robust parsing of the mount format and to give - // precise errors regarding supported format versus suppored options. + // precise errors regarding supported format versus supported options. for _, mount := range config.MountsFlag { arr := strings.SplitN(mount, ",", 2) if len(arr) < 2 { @@ -820,7 +820,7 @@ func (config *CreateConfig) addContainerInitBinary(path string) (spec.Mount, err return mount, nil } -// Supercede existing mounts in the spec with new, user-specified mounts. +// Supersede existing mounts in the spec with new, user-specified mounts. // TODO: Should we unmount subtree mounts? E.g., if /tmp/ is mounted by // one mount, and we already have /tmp/a and /tmp/b, should we remove // the /tmp/a and /tmp/b mounts in favor of the more general /tmp? diff --git a/pkg/trust/trust.go b/pkg/trust/trust.go index b1febbe81..60de099fa 100644 --- a/pkg/trust/trust.go +++ b/pkg/trust/trust.go @@ -139,7 +139,7 @@ func LoadAndMergeConfig(dirPath string) (*RegistryConfiguration, error) { return &mergedConfig, nil } -// HaveMatchRegistry checks if trust settings for the registry have been configed in yaml file +// HaveMatchRegistry checks if trust settings for the registry have been configured in yaml file func HaveMatchRegistry(key string, registryConfigs *RegistryConfiguration) *RegistryNamespace { searchKey := key if !strings.Contains(searchKey, "/") { diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 633d8a124..6906b26d5 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -84,7 +84,7 @@ func ParseChanges(option string) (key string, vals []string, err error) { if len(tokens) < 2 { return "", []string{}, fmt.Errorf("invalid key value %s", option) } - key = strings.Trim(tokens[0], " ") // Need to trim whitespace part of delimeter. + key = strings.Trim(tokens[0], " ") // Need to trim whitespace part of delimiter. val = tokens[1] if strings.Contains(tokens[1], "[") && strings.Contains(tokens[1], "]") { //Trim '[',']' if exist. |