Source code documentation updates (#9)

This change adds documentation to quite a few existing public types that
didn't have a blurb before.

Additionally, this fixes a couple things that I think either didn't make
sense when going to document them:
- Rename ConnectionStream to VsockConnectionStream. This type only
functions for vsock connections.
- Deletes NsLock+Closure. This was not used anywhere.
- Rename ContainerizationOCI/Config.swift to ImageConfig.swift.

Signed-off-by: Danny Canter <danny_canter@apple.com>
This commit is contained in:
Danny Canter
2025-06-05 16:16:18 -07:00
committed by Kathryn Baldauf
parent 8d880efc36
commit 6bc4bf5124
36 changed files with 98 additions and 53 deletions
@@ -17,6 +17,8 @@
import Foundation
import Synchronization
/// Async friendly wrapper around DispatchSourceSignal. Provides an AsyncStream
/// interface to get notified of received signals.
public final class AsyncSignalHandler: Sendable {
/// An async stream that returns the signal that was caught, if ever
public var signals: AsyncStream<Int32> {
+1
View File
@@ -16,6 +16,7 @@
import Foundation
/// Trivial type to discover information about a given file (uid, gid, mode...).
public struct File: Sendable {
public enum Error: Swift.Error, CustomStringConvertible {
case errno(_ e: Int32)
@@ -17,6 +17,7 @@
#if os(macOS)
import Foundation
/// Holds the result of a query to the keychain.
public struct KeychainQueryResult {
public var account: String
public var data: String
@@ -24,9 +25,11 @@ public struct KeychainQueryResult {
public var createdDate: Date
}
/// Type that facilitates interacting with the macOS keychain.
public struct KeychainQuery {
public init() {}
/// Save a value to the keychain.
public func save(id: String, host: String, user: String, token: String) throws {
if try exists(id: id, host: host) {
try delete(id: id, host: host)
@@ -48,6 +51,7 @@ public struct KeychainQuery {
guard status == errSecSuccess else { throw Self.Error.unhandledError(status: status) }
}
/// Delete a value from the keychain.
public func delete(id: String, host: String) throws {
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
@@ -61,6 +65,7 @@ public struct KeychainQuery {
}
}
/// Retrieve a value from the keychain.
public func get(id: String, host: String) throws -> KeychainQueryResult? {
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
@@ -113,6 +118,7 @@ public struct KeychainQuery {
return true
}
/// Check if a value exists in the keychain.
public func exists(id: String, host: String) throws -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
+2 -1
View File
@@ -27,7 +27,8 @@ import Glibc
import Foundation
import Synchronization
/// Register file descriptors to receive events.
/// Register file descriptors to receive events via Linux's
/// epoll syscall surface.
public final class Epoll: Sendable {
public typealias Mask = Int32
public typealias Handler = (@Sendable (Mask) -> Void)
+21 -14
View File
@@ -26,10 +26,10 @@ private let _mount = Glibc.mount
private let _umount = Glibc.umount2
#endif
/// Mount package modeled closely from containerd's: https://github.com/containerd/containerd/tree/main/core/mount
/// Technically, this would be fine in the Linux subdirectory as it's Linux specific for now, but that
/// might not always be the case.
// Mount package modeled closely from containerd's: https://github.com/containerd/containerd/tree/main/core/mount
/// `Mount` models a Linux mount (although potentially could be used on other unix platforms), and
/// provides a simple interface to mount what the type describes.
public struct Mount: Sendable {
// Type specifies the host-specific of the mount.
public var type: String
@@ -99,6 +99,7 @@ extension Mount {
}
}
/// Whether the mount is read only.
public var readOnly: Bool {
for option in self.options {
if option == "ro" {
@@ -108,6 +109,23 @@ extension Mount {
return false
}
/// Mount the mount relative to `root` with the current set of data in the object.
/// Optionally provide `createWithPerms` to set the permissions for the directory that
/// it will be mounted at.
public func mount(root: String, createWithPerms: Int16? = nil) throws {
var rootURL = URL(fileURLWithPath: root)
rootURL = rootURL.resolvingSymlinksInPath()
rootURL = rootURL.appendingPathComponent(self.target)
try self.mountToTarget(target: rootURL.path, createWithPerms: createWithPerms)
}
/// Mount the mount with the current set of data in the object. Optionally
/// provide `createWithPerms` to set the permissions for the directory that
/// it will be mounted at.
public func mount(createWithPerms: Int16? = nil) throws {
try self.mountToTarget(target: self.target, createWithPerms: createWithPerms)
}
private func mountToTarget(target: String, createWithPerms: Int16?) throws {
let pageSize = sysconf(_SC_PAGESIZE)
@@ -154,17 +172,6 @@ extension Mount {
}
}
public func mount(root: String, createWithPerms: Int16? = nil) throws {
var rootURL = URL(fileURLWithPath: root)
rootURL = rootURL.resolvingSymlinksInPath()
rootURL = rootURL.appendingPathComponent(self.target)
try self.mountToTarget(target: rootURL.path, createWithPerms: createWithPerms)
}
public func mount(createWithPerms: Int16? = nil) throws {
try self.mountToTarget(target: self.target, createWithPerms: createWithPerms)
}
private func mkdirAll(_ name: String, _ perm: Int16) throws {
try FileManager.default.createDirectory(
atPath: name,
@@ -1,27 +0,0 @@
//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the containerization project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
import Foundation
extension NSLock {
/// lock during the execution of the provided function
public func lock<T>(_ fn: () throws -> T) rethrows -> T {
self.lock()
defer { self.unlock() }
return try fn()
}
}
+2
View File
@@ -16,6 +16,8 @@
import Foundation
/// `Path` provides utilities to look for binaries in the current PATH,
/// or to return the current PATH.
public struct Path {
/// lookPath looks up an executable's path from $PATH
public static func lookPath(_ name: String) -> URL? {
+1
View File
@@ -16,6 +16,7 @@
import Foundation
/// Helper type with utilities to parse and manipulate unix signals.
public struct Signals {
public static func allNumeric() -> [Int32] {
Array(Signals.all.values)
@@ -44,6 +44,7 @@ let sysConnect = connect
let sysIoctl: @convention(c) (CInt, CUnsignedLong, UnsafeMutableRawPointer) -> CInt = ioctl
#endif
/// Thread-safe socket wrapper.
public final class Socket: Sendable {
public enum TimeoutOption {
case send
@@ -24,6 +24,7 @@ import Darwin
#error("SocketType not supported on this platform.")
#endif
/// Protocol used to describe the family of socket to be created with `Socket`.
public protocol SocketType: Sendable, CustomStringConvertible {
var domain: Int32 { get }
var type: Int32 { get }
@@ -27,6 +27,7 @@ let _SOCK_STREAM = SOCK_STREAM
#error("UnixType not supported on this platform.")
#endif
/// Unix domain socket variant of `SocketType`.
public struct UnixType: SocketType, Sendable, CustomStringConvertible {
public var domain: Int32 { AF_UNIX }
public var type: Int32 { _SOCK_STREAM }
@@ -26,6 +26,7 @@ import Darwin
#error("VsockType not supported on this platform.")
#endif
/// Vsock variant of `SocketType`.
public struct VsockType: SocketType, Sendable {
public var domain: Int32 { AF_VSOCK }
public var type: Int32 { _SOCK_STREAM }
+1
View File
@@ -24,6 +24,7 @@ import Darwin
#error("retryingSyscall not supported on this platform.")
#endif
/// Helper type to deal with running system calls.
public struct Syscall {
/// Retry a syscall on EINTR.
public static func retrying<T: FixedWidthInteger>(_ closure: () -> T) -> T {
+1
View File
@@ -16,6 +16,7 @@
import Foundation
/// Helper type to deal with system control functionalities.
public struct Sysctl {
#if os(macOS)
/// Simple `sysctlbyname` wrapper.
@@ -16,6 +16,8 @@
import Foundation
/// `Terminal` provides a clean interface to deal with terminal
/// interactions on Unix platforms.
public struct Terminal: Sendable {
private let initState: termios?
+2
View File
@@ -17,6 +17,8 @@
import ContainerizationError
import Foundation
/// `User` provides utilities to ensure that a given username exists in
/// /etc/passwd (and /etc/group).
public enum User {
private static let passwdFile = "/etc/passwd"
private static let groupFile = "/etc/group"