(ctx context.Context, opts runtime.CreateOpts)
| 380 | } |
| 381 | |
| 382 | func (m *TaskManager) validateRuntimeFeatures(ctx context.Context, opts runtime.CreateOpts) error { |
| 383 | var spec specs.Spec |
| 384 | if err := typeurl.UnmarshalTo(opts.Spec, &spec); err != nil { |
| 385 | return fmt.Errorf("unmarshal spec: %w", err) |
| 386 | } |
| 387 | |
| 388 | // Only ask for the PluginInfo if idmap mounts are used. |
| 389 | if !usesIDMapMounts(spec) { |
| 390 | return nil |
| 391 | } |
| 392 | |
| 393 | topts := opts.TaskOptions |
| 394 | if topts == nil || topts.GetValue() == nil { |
| 395 | topts = opts.RuntimeOptions |
| 396 | } |
| 397 | |
| 398 | pInfo, err := m.PluginInfo(ctx, &apitypes.RuntimeRequest{RuntimePath: opts.Runtime, Options: typeurl.MarshalProto(topts)}) |
| 399 | if err != nil { |
| 400 | return fmt.Errorf("runtime info: %w", err) |
| 401 | } |
| 402 | |
| 403 | pluginInfo, ok := pInfo.(*apitypes.RuntimeInfo) |
| 404 | if !ok { |
| 405 | return fmt.Errorf("invalid runtime info type: %T", pInfo) |
| 406 | } |
| 407 | |
| 408 | feat, err := typeurl.UnmarshalAny(pluginInfo.Features) |
| 409 | if err != nil { |
| 410 | return fmt.Errorf("unmarshal runtime features: %w", err) |
| 411 | } |
| 412 | |
| 413 | // runc-compatible runtimes silently ignores features it doesn't know about. But ignoring |
| 414 | // our request to use idmap mounts can break permissions in the volume, so let's make sure |
| 415 | // it supports it. For more info, see: |
| 416 | // https://github.com/opencontainers/runtime-spec/pull/1219 |
| 417 | // |
| 418 | features, ok := feat.(*features.Features) |
| 419 | if !ok { |
| 420 | // Leave alone non runc-compatible runtimes that don't provide the features info, |
| 421 | // they might not be affected by this. |
| 422 | return nil |
| 423 | } |
| 424 | |
| 425 | if err := supportsIDMapMounts(features); err != nil { |
| 426 | return fmt.Errorf("idmap mounts not supported: %w", err) |
| 427 | } |
| 428 | |
| 429 | return nil |
| 430 | } |
| 431 | |
| 432 | func usesIDMapMounts(spec specs.Spec) bool { |
| 433 | for _, m := range spec.Mounts { |
no test coverage detected