Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Sources/ContainerClient/Core/ContainerConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ public struct ContainerConfiguration: Sendable, Codable {
public var rosetta: Bool = false
/// Initial or main process of the container.
public var initProcess: ProcessConfiguration
/// Platform for the container
/// Platform for the container.
public var platform: ContainerizationOCI.Platform = .current
/// Resource values for the container.
public var resources: Resources = .init()
/// Name of the runtime that supports the container
/// Name of the runtime that supports the container.
public var runtimeHandler: String = "container-runtime-linux"
/// Configure exposing virtualization support in the container.
public var virtualization: Bool = false
/// Enable SSH agent socket forwarding from host to container.
public var ssh: Bool = false

enum CodingKeys: String, CodingKey {
case id
Expand All @@ -65,6 +67,7 @@ public struct ContainerConfiguration: Sendable, Codable {
case resources
case runtimeHandler
case virtualization
case ssh
}

/// Create a configuration from the supplied Decoder, initializing missing
Expand Down Expand Up @@ -99,6 +102,7 @@ public struct ContainerConfiguration: Sendable, Codable {
resources = try container.decodeIfPresent(Resources.self, forKey: .resources) ?? .init()
runtimeHandler = try container.decodeIfPresent(String.self, forKey: .runtimeHandler) ?? "container-runtime-linux"
virtualization = try container.decodeIfPresent(Bool.self, forKey: .virtualization) ?? false
ssh = try container.decodeIfPresent(Bool.self, forKey: .ssh) ?? false
}

public struct DNSConfiguration: Sendable, Codable {
Expand Down
3 changes: 3 additions & 0 deletions Sources/ContainerClient/Flags.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ public struct Flags {
"Expose virtualization capabilities to the container. (Host must have nested virtualization support, and guest kernel must have virtualization capabilities enabled)"
)
public var virtualization: Bool = false

@Flag(name: .customLong("ssh"), help: "Forward SSH agent socket to container")
public var ssh = false
}

public struct Progress: ParsableArguments {
Expand Down
2 changes: 2 additions & 0 deletions Sources/ContainerClient/Utility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ public struct Utility {
// to enable socket forwarding from container to host.
config.publishedSockets = try Parser.publishSockets(management.publishSockets)

config.ssh = management.ssh

return (config, kernel)
}

Expand Down
23 changes: 23 additions & 0 deletions Sources/Services/ContainerSandboxService/SandboxService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public actor SandboxService {
private var processes: [String: ProcessInfo] = [:]
private var socketForwarders: [SocketForwarderResult] = []

private static let sshAuthSocketGuestPath = "/run/host-services/ssh-auth.sock"
private static let sshAuthSocketEnvVar = "SSH_AUTH_SOCK"

/// Create an instance with a bundle that describes the container.
///
/// - Parameters:
Expand Down Expand Up @@ -718,6 +721,17 @@ public actor SandboxService {
czConfig.sockets.append(socketConfig)
}

if config.ssh {
if let sshSocket = Foundation.ProcessInfo.processInfo.environment[Self.sshAuthSocketEnvVar] {
let socketConfig = UnixSocketConfiguration(
source: URL(fileURLWithPath: sshSocket),
destination: URL(fileURLWithPath: Self.sshAuthSocketGuestPath),
direction: .into
)
czConfig.sockets.append(socketConfig)
}
}

czConfig.hostname = config.id

if let dns = config.dns {
Expand Down Expand Up @@ -748,6 +762,15 @@ public actor SandboxService {
) {
czConfig.process.arguments = [process.executable] + process.arguments
czConfig.process.environmentVariables = process.environment

if czConfig.sockets.contains(where: {
$0.destination == URL(fileURLWithPath: Self.sshAuthSocketGuestPath)
}) {
if !czConfig.process.environmentVariables.contains(where: { $0.starts(with: "\(Self.sshAuthSocketEnvVar)=") }) {
czConfig.process.environmentVariables.append("\(Self.sshAuthSocketEnvVar)=\(Self.sshAuthSocketGuestPath)")
}
}

czConfig.process.terminal = process.terminal
czConfig.process.workingDirectory = process.workingDirectory
czConfig.process.rlimits = process.rlimits.map {
Expand Down