oci.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package specs
  2. import (
  3. "errors"
  4. "fmt"
  5. spec "github.com/opencontainers/runtime-spec/specs-go"
  6. )
  7. // ApplyOCIEditsForDevice applies devices OCI edits, in other words
  8. // it finds the device in the CDI spec and applies the OCI patches that device
  9. // requires to the OCI specification.
  10. func ApplyOCIEditsForDevice(config *spec.Spec, cdi *Spec, dev string) error {
  11. for _, d := range cdi.Devices {
  12. if d.Name != dev {
  13. continue
  14. }
  15. return ApplyEditsToOCISpec(config, &d.ContainerEdits)
  16. }
  17. return fmt.Errorf("CDI: device %q not found for spec %q", dev, cdi.Kind)
  18. }
  19. // ApplyOCIEdits applies the OCI edits the CDI spec declares globally
  20. func ApplyOCIEdits(config *spec.Spec, cdi *Spec) error {
  21. return ApplyEditsToOCISpec(config, &cdi.ContainerEdits)
  22. }
  23. // ApplyEditsToOCISpec applies the specified edits to the OCI spec.
  24. func ApplyEditsToOCISpec(config *spec.Spec, edits *ContainerEdits) error {
  25. if config == nil {
  26. return errors.New("spec is nil")
  27. }
  28. if edits == nil {
  29. return nil
  30. }
  31. if len(edits.Env) > 0 {
  32. if config.Process == nil {
  33. config.Process = &spec.Process{}
  34. }
  35. config.Process.Env = append(config.Process.Env, edits.Env...)
  36. }
  37. for _, d := range edits.DeviceNodes {
  38. if config.Linux == nil {
  39. config.Linux = &spec.Linux{}
  40. }
  41. config.Linux.Devices = append(config.Linux.Devices, d.ToOCI())
  42. }
  43. for _, m := range edits.Mounts {
  44. config.Mounts = append(config.Mounts, m.ToOCI())
  45. }
  46. for _, h := range edits.Hooks {
  47. if config.Hooks == nil {
  48. config.Hooks = &spec.Hooks{}
  49. }
  50. switch h.HookName {
  51. case "prestart":
  52. config.Hooks.Prestart = append(config.Hooks.Prestart, h.ToOCI())
  53. case "createRuntime":
  54. config.Hooks.CreateRuntime = append(config.Hooks.CreateRuntime, h.ToOCI())
  55. case "createContainer":
  56. config.Hooks.CreateContainer = append(config.Hooks.CreateContainer, h.ToOCI())
  57. case "startContainer":
  58. config.Hooks.StartContainer = append(config.Hooks.StartContainer, h.ToOCI())
  59. case "poststart":
  60. config.Hooks.Poststart = append(config.Hooks.Poststart, h.ToOCI())
  61. case "poststop":
  62. config.Hooks.Poststop = append(config.Hooks.Poststop, h.ToOCI())
  63. default:
  64. fmt.Printf("CDI: Unknown hook %q\n", h.HookName)
  65. }
  66. }
  67. return nil
  68. }
  69. // ToOCI returns the opencontainers runtime Spec Hook for this Hook.
  70. func (h *Hook) ToOCI() spec.Hook {
  71. return spec.Hook{
  72. Path: h.Path,
  73. Args: h.Args,
  74. Env: h.Env,
  75. Timeout: h.Timeout,
  76. }
  77. }
  78. // ToOCI returns the opencontainers runtime Spec Mount for this Mount.
  79. func (m *Mount) ToOCI() spec.Mount {
  80. return spec.Mount{
  81. Source: m.HostPath,
  82. Destination: m.ContainerPath,
  83. Options: m.Options,
  84. Type: m.Type,
  85. }
  86. }
  87. // ToOCI returns the opencontainers runtime Spec LinuxDevice for this DeviceNode.
  88. func (d *DeviceNode) ToOCI() spec.LinuxDevice {
  89. return spec.LinuxDevice{
  90. Path: d.Path,
  91. Type: d.Type,
  92. Major: d.Major,
  93. Minor: d.Minor,
  94. FileMode: d.FileMode,
  95. UID: d.UID,
  96. GID: d.GID,
  97. }
  98. }