mirror of
https://github.com/apple/container.git
synced 2026-09-12 18:55:43 +00:00
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:
@@ -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> {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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? {
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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?
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user