36 lines
2.5 KiB
Swift
36 lines
2.5 KiB
Swift
import Foundation
|
|
|
|
public enum VolumeInventory {
|
|
/// Managed volumes are enriched with configured references. Persistent host
|
|
/// mounts are displayed separately and can never be deleted as volumes.
|
|
public static func combine(volumes: [Resource], containers: [Resource], includeHostMounts: Bool = true) -> [Resource] {
|
|
var result = volumes
|
|
var uses: [String: Set<String>] = [:]
|
|
var host: [String: Resource] = [:]
|
|
for container in containers {
|
|
guard let data = container.raw.data(using: .utf8), let row = try? JSONSerialization.jsonObject(with: data) as? [String: Any], let cfg = row["configuration"] as? [String: Any], let mounts = cfg["mounts"] as? [[String: Any]] else { continue }
|
|
for mount in mounts {
|
|
let type = mount["type"] as? [String: Any] ?? [:]
|
|
let source = mount["source"] as? String ?? ""
|
|
let destination = mount["destination"] as? String ?? ""
|
|
let reference = "\(container.name):\(destination)"
|
|
if let volume = type["volume"] as? [String: Any], let name = volume["name"] as? String { uses[name, default: []].insert(reference); continue }
|
|
if let volume = volumes.first(where: { $0.source == source && !source.isEmpty }) { uses[volume.id, default: []].insert(reference); continue }
|
|
guard includeHostMounts, !source.isEmpty, type["virtiofs"] != nil || type["block"] != nil else { continue }
|
|
let id = "host:" + source
|
|
var item = host[id] ?? Resource(id: id, name: URL(fileURLWithPath: source).lastPathComponent, state: "Referenced", image: "—", project: "", service: "", ports: "—", raw: ContainerService.pretty(mount))
|
|
item.source = source; item.storageKind = type["block"] == nil ? "Bind mount" : "Disk mount"; item.readOnlyStorage = true
|
|
item.driver = type["block"] == nil ? "virtiofs" : "block"; item.format = "host"; item.usedBy = ""
|
|
host[id] = item; uses[id, default: []].insert(reference)
|
|
}
|
|
}
|
|
result += host.values
|
|
for index in result.indices {
|
|
let references = uses[result[index].id] ?? []
|
|
result[index].usedBy = references.isEmpty ? "No container references" : references.sorted().joined(separator: ", ")
|
|
result[index].state = references.isEmpty ? "Unreferenced" : "Referenced"
|
|
}
|
|
return result.sorted { ($0.readOnlyStorage ? 1 : 0, $0.name) < ($1.readOnlyStorage ? 1 : 0, $1.name) }
|
|
}
|
|
}
|