containerization-framework 0.10.0

Rust bindings for Apple's Containerization framework: Linux containers in lightweight VMs, in-process and without a daemon.
//===----------------------------------------------------------------------===//
// The OCI runtime spec's cgroup resources, both ways: memory, CPU, block I/O,
// device rules and the rest. The Rust side is
// `bridge::accessors::spec::resources`.
//===----------------------------------------------------------------------===//

import ContainerizationOCI
import Foundation

// MARK: Rust to Swift

extension LinuxResources {
  init(_ resources: RustLinuxResourcesRef) {
    self.init(
      devices: list(resources.devicesLen()) { LinuxDeviceCgroup(resources.devicesAt($0)) },
      memory: resources.hasMemory() ? LinuxMemory(resources.memory()) : nil,
      cpu: resources.hasCpu() ? LinuxCPU(resources.cpu()) : nil,
      pids: resources.pidsLimit().map { LinuxPids(limit: $0) },
      blockIO: resources.hasBlockIO() ? LinuxBlockIO(resources.blockIO()) : nil,
      hugepageLimits: list(resources.hugepageLimitsLen()) {
        LinuxHugepageLimit(
          pagesize: resources.hugepageLimitPagesizeAt($0).toString(),
          limit: resources.hugepageLimitLimitAt($0)
        )
      },
      network: resources.hasNetwork()
        ? LinuxNetwork(
          classID: resources.networkClassID(),
          priorities: list(resources.networkPrioritiesLen()) {
            LinuxInterfacePriority(
              name: resources.networkPriorityNameAt($0).toString(),
              priority: resources.networkPriorityAt($0)
            )
          }
        ) : nil,
      rdma: resources.hasRdma()
        ? Dictionary(
          list(resources.rdmaLen()) {
            (
              resources.rdmaKeyAt($0).toString(),
              LinuxRdma(hcsHandles: resources.rdmaHcsHandlesAt($0), hcaObjects: resources.rdmaHcaObjectsAt($0))
            )
          },
          uniquingKeysWith: { _, last in last }
        ) : nil
    )
    // The initializer can't make `unified` nil.
    unified =
      resources.hasUnified()
      ? dictionary(resources.unifiedLen(), resources.unifiedKeyAt, resources.unifiedValueAt) : nil
  }
}

extension LinuxMemory {
  init(_ memory: RustLinuxMemoryRef) {
    self.init(
      limit: memory.limit(),
      reservation: memory.reservation(),
      swap: memory.swap(),
      kernel: memory.kernel(),
      kernelTCP: memory.kernelTCP(),
      swappiness: memory.swappiness(),
      disableOOMKiller: memory.disableOOMKiller(),
      useHierarchy: memory.useHierarchy(),
      checkBeforeUpdate: memory.checkBeforeUpdate()
    )
  }
}

extension LinuxCPU {
  init(_ cpu: RustLinuxCPURef) {
    self.init(
      shares: cpu.shares(),
      quota: cpu.quota(),
      burst: cpu.burst(),
      period: cpu.period(),
      realtimeRuntime: cpu.realtimeRuntime(),
      realtimePeriod: cpu.realtimePeriod(),
      cpus: cpu.cpus().toString(),
      mems: cpu.mems().toString(),
      idle: cpu.idle()
    )
  }
}

extension LinuxBlockIO {
  init(_ blockIO: RustLinuxBlockIORef) {
    func throttle(_ kind: ThrottleKind) -> [LinuxThrottleDevice] {
      list(blockIO.throttleLen(kind)) {
        LinuxThrottleDevice(
          major: blockIO.throttleMajorAt(kind, $0),
          minor: blockIO.throttleMinorAt(kind, $0),
          rate: blockIO.throttleRateAt(kind, $0)
        )
      }
    }

    self.init(
      weight: blockIO.weight(),
      leafWeight: blockIO.leafWeight(),
      weightDevice: list(blockIO.weightDeviceLen()) {
        LinuxWeightDevice(
          major: blockIO.weightDeviceMajorAt($0),
          minor: blockIO.weightDeviceMinorAt($0),
          weight: blockIO.weightDeviceWeightAt($0),
          leafWeight: blockIO.weightDeviceLeafWeightAt($0)
        )
      },
      throttleReadBpsDevice: throttle(.ReadBps),
      throttleWriteBpsDevice: throttle(.WriteBps),
      throttleReadIOPSDevice: throttle(.ReadIops),
      throttleWriteIOPSDevice: throttle(.WriteIops)
    )
  }
}

extension LinuxDeviceCgroup {
  init(_ device: RustLinuxDeviceCgroupRef) {
    self.init(
      allow: device.allow(),
      type: device.deviceType().toString(),
      major: device.major(),
      minor: device.minor(),
      access: device.access()?.toString()
    )
  }
}

// MARK: Swift to Rust

extension CzOutcome {
  // `LinuxResources`.

  func resourcesDevices() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).devices)
  }

  func resourcesMemory() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).memory)
  }

  func resourcesCpu() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).cpu)
  }

  func resourcesPids() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).pids)
  }

  func resourcesBlockIO() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).blockIO)
  }

  func resourcesHugepageLimits() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).hugepageLimits)
  }

  func resourcesNetwork() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).network)
  }

  func resourcesRdma() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).rdma)
  }

  func resourcesUnified() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxResources).unified)
  }

  // The types only `LinuxResources` holds.

  func memoryLimit() -> Int64? {
    (taken() as LinuxMemory).limit
  }

  func memoryReservation() -> Int64? {
    (taken() as LinuxMemory).reservation
  }

  func memorySwap() -> Int64? {
    (taken() as LinuxMemory).swap
  }

  func memoryKernel() -> Int64? {
    (taken() as LinuxMemory).kernel
  }

  func memoryKernelTCP() -> Int64? {
    (taken() as LinuxMemory).kernelTCP
  }

  func memorySwappiness() -> UInt64? {
    (taken() as LinuxMemory).swappiness
  }

  func memoryDisableOOMKiller() -> Bool? {
    (taken() as LinuxMemory).disableOOMKiller
  }

  func memoryUseHierarchy() -> Bool? {
    (taken() as LinuxMemory).useHierarchy
  }

  func memoryCheckBeforeUpdate() -> Bool? {
    (taken() as LinuxMemory).checkBeforeUpdate
  }

  func cpuShares() -> UInt64? {
    (taken() as LinuxCPU).shares
  }

  func cpuQuota() -> Int64? {
    (taken() as LinuxCPU).quota
  }

  func cpuBurst() -> UInt64? {
    (taken() as LinuxCPU).burst
  }

  func cpuPeriod() -> UInt64? {
    (taken() as LinuxCPU).period
  }

  func cpuRealtimeRuntime() -> Int64? {
    (taken() as LinuxCPU).realtimeRuntime
  }

  func cpuRealtimePeriod() -> Int64? {
    (taken() as LinuxCPU).realtimePeriod
  }

  func cpuCpus() -> String {
    (taken() as LinuxCPU).cpus
  }

  func cpuMems() -> String {
    (taken() as LinuxCPU).mems
  }

  func cpuIdle() -> Int64? {
    (taken() as LinuxCPU).idle
  }

  func pidsLimit() -> Int64 {
    (taken() as LinuxPids).limit
  }

  func blockIOWeight() -> UInt16? {
    (taken() as LinuxBlockIO).weight
  }

  func blockIOLeafWeight() -> UInt16? {
    (taken() as LinuxBlockIO).leafWeight
  }

  func blockIOWeightDevice() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxBlockIO).weightDevice)
  }

  func blockIOThrottle(kind: ThrottleKind) -> CzOutcome {
    let blockIO: LinuxBlockIO = taken()
    let devices: [LinuxThrottleDevice] =
      switch kind {
      case .ReadBps: blockIO.throttleReadBpsDevice
      case .WriteBps: blockIO.throttleWriteBpsDevice
      case .ReadIops: blockIO.throttleReadIOPSDevice
      case .WriteIops: blockIO.throttleWriteIOPSDevice
      }

    return CzOutcome.holding(devices)
  }

  func weightDeviceMajor() -> Int64 {
    (taken() as LinuxWeightDevice).major
  }

  func weightDeviceMinor() -> Int64 {
    (taken() as LinuxWeightDevice).minor
  }

  func weightDeviceWeight() -> UInt16? {
    (taken() as LinuxWeightDevice).weight
  }

  func weightDeviceLeafWeight() -> UInt16? {
    (taken() as LinuxWeightDevice).leafWeight
  }

  func throttleDeviceMajor() -> Int64 {
    (taken() as LinuxThrottleDevice).major
  }

  func throttleDeviceMinor() -> Int64 {
    (taken() as LinuxThrottleDevice).minor
  }

  func throttleDeviceRate() -> UInt64 {
    (taken() as LinuxThrottleDevice).rate
  }

  func hugepageLimitPagesize() -> String {
    (taken() as LinuxHugepageLimit).pagesize
  }

  func hugepageLimitLimit() -> UInt64 {
    (taken() as LinuxHugepageLimit).limit
  }

  func networkClassID() -> UInt32? {
    (taken() as LinuxNetwork).classID
  }

  func networkPriorities() -> CzOutcome {
    CzOutcome.holding((taken() as LinuxNetwork).priorities)
  }

  func interfacePriorityName() -> String {
    (taken() as LinuxInterfacePriority).name
  }

  func interfacePriorityPriority() -> UInt32 {
    (taken() as LinuxInterfacePriority).priority
  }

  func rdmaHcsHandles() -> UInt32? {
    (taken() as LinuxRdma).hcsHandles
  }

  func rdmaHcaObjects() -> UInt32? {
    (taken() as LinuxRdma).hcaObjects
  }

  // `LinuxDeviceCgroup`.

  func deviceCgroupAllow() -> Bool {
    (taken() as LinuxDeviceCgroup).allow
  }

  func deviceCgroupType() -> String {
    (taken() as LinuxDeviceCgroup).type
  }

  func deviceCgroupMajor() -> Int64? {
    (taken() as LinuxDeviceCgroup).major
  }

  func deviceCgroupMinor() -> Int64? {
    (taken() as LinuxDeviceCgroup).minor
  }

  func deviceCgroupAccess() -> String? {
    (taken() as LinuxDeviceCgroup).access
  }
}