mirror of
https://github.com/apple/container.git
synced 2026-11-07 06:25:11 +00:00
Cleans up option groups, container subcommand help. (#647)
- Part of #515. - Add titles to option groups for container subcommands. - Order option groups and container subcommand options alphabetically. - Use `container-id` and `container-ids` consistently as argument names. - Shorten long valueNames to avoid option column overflow in help output where possible. - Replace customShort and customLong with short, long, and shortAndLong where possible. - Always place global options and arguments after alphabetized command-specific options. - Rename RunCommand to ContainerRun and relocate it. - Rename Executable to ContainerCLI. ## Type of Change - [ ] Bug fix - [ ] New feature - [x] Breaking change (if you're depending on `RunCommand`, renamed). - [ ] Documentation update ## Motivation and Context See #385. ## Testing - [ ] Tested locally - [ ] Added/updated tests - [ ] Added/updated docs
This commit is contained in:
1 parent
7df9763aa5
commit
f3b33ffc45
16 files changed
+375
-321
No files matched your search
@@ -19,7 +19,7 @@ import ContainerClient
|
||||
import ContainerCommands
|
||||
|
||||
@main
|
||||
public struct Executable: AsyncParsableCommand {
|
||||
public struct ContainerCLI: AsyncParsableCommand {
|
||||
public init() {}
|
||||
|
||||
@Argument(parsing: .captureForPassthrough)
|
||||
@@ -29,43 +29,49 @@ public struct Flags {
|
||||
public struct Process: ParsableArguments {
|
||||
public init() {}
|
||||
|
||||
@Option(
|
||||
name: [.customLong("cwd"), .customShort("w"), .customLong("workdir")],
|
||||
help: "Current working directory for the container")
|
||||
public var cwd: String?
|
||||
|
||||
@Option(name: [.customLong("env"), .customShort("e")], help: "Set environment variables")
|
||||
@Option(name: .shortAndLong, help: "Set environment variables (format: key=value)")
|
||||
public var env: [String] = []
|
||||
|
||||
@Option(name: .customLong("env-file"), help: "Read in a file of environment variables")
|
||||
@Option(
|
||||
name: .long,
|
||||
help: "Read in a file of environment variables (key=value format, ignores # comments and blank lines)"
|
||||
)
|
||||
public var envFile: [String] = []
|
||||
|
||||
@Option(name: .customLong("uid"), help: "Set the uid for the process")
|
||||
public var uid: UInt32?
|
||||
|
||||
@Option(name: .customLong("gid"), help: "Set the gid for the process")
|
||||
@Option(name: .long, help: "Set the group ID for the process")
|
||||
public var gid: UInt32?
|
||||
|
||||
@Flag(name: [.customLong("interactive"), .customShort("i")], help: "Keep Stdin open even if not attached")
|
||||
@Flag(name: .shortAndLong, help: "Keep the standard input open even if not attached")
|
||||
public var interactive = false
|
||||
|
||||
@Flag(name: [.customLong("tty"), .customShort("t")], help: "Open a tty with the process")
|
||||
@Flag(name: .shortAndLong, help: "Open a TTY with the process")
|
||||
public var tty = false
|
||||
|
||||
@Option(name: [.customLong("user"), .customShort("u")], help: "Set the user for the process")
|
||||
@Option(name: .shortAndLong, help: "Set the user for the process (format: name|uid[:gid])")
|
||||
public var user: String?
|
||||
|
||||
@Option(name: .long, help: "Set the user ID for the process")
|
||||
public var uid: UInt32?
|
||||
|
||||
@Option(
|
||||
name: [.customShort("w"), .customLong("workdir"), .long],
|
||||
help: .init(
|
||||
"Set the initial working directory inside the container",
|
||||
valueName: "dir"
|
||||
)
|
||||
)
|
||||
public var cwd: String?
|
||||
}
|
||||
|
||||
public struct Resource: ParsableArguments {
|
||||
public init() {}
|
||||
|
||||
@Option(name: [.customLong("cpus"), .customShort("c")], help: "Number of CPUs to allocate to the container")
|
||||
@Option(name: .shortAndLong, help: "Number of CPUs to allocate to the container")
|
||||
public var cpus: Int64?
|
||||
|
||||
@Option(
|
||||
name: [.customLong("memory"), .customShort("m")],
|
||||
help:
|
||||
"Amount of memory (1MiByte granularity), with optional K, M, G, T, or P suffix"
|
||||
name: .shortAndLong,
|
||||
help: "Amount of memory (1MiByte granularity), with optional K, M, G, T, or P suffix"
|
||||
)
|
||||
public var memory: String?
|
||||
}
|
||||
@@ -84,83 +90,115 @@ public struct Flags {
|
||||
public struct Management: ParsableArguments {
|
||||
public init() {}
|
||||
|
||||
@Flag(name: [.customLong("detach"), .short], help: "Run the container and detach from the process")
|
||||
public var detach = false
|
||||
|
||||
@Option(name: .customLong("entrypoint"), help: "Override the entrypoint of the image")
|
||||
public var entryPoint: String?
|
||||
|
||||
@Option(name: .customLong("mount"), help: "Add a mount to the container (type=<>,source=<>,target=<>,readonly)")
|
||||
public var mounts: [String] = []
|
||||
|
||||
@Option(name: [.customLong("publish"), .short], help: "Publish a port from container to host (format: [host-ip:]host-port:container-port[/protocol])")
|
||||
public var publishPorts: [String] = []
|
||||
|
||||
@Option(name: .customLong("publish-socket"), help: "Publish a socket from container to host (format: host_path:container_path)")
|
||||
public var publishSockets: [String] = []
|
||||
|
||||
@Option(name: .customLong("tmpfs"), help: "Add a tmpfs mount to the container at the given path")
|
||||
public var tmpFs: [String] = []
|
||||
|
||||
@Option(name: .customLong("name"), help: "Assign a name to the container. If excluded will be a generated UUID")
|
||||
public var name: String?
|
||||
|
||||
@Flag(name: [.customLong("remove"), .customLong("rm")], help: "Remove the container after it stops")
|
||||
public var remove = false
|
||||
|
||||
@Option(name: .customLong("platform"), help: "Platform for the image if it's multi-platform. This takes precedence over --os and --arch")
|
||||
public var platform: String?
|
||||
|
||||
@Option(name: .customLong("os"), help: "Set OS if image can target multiple operating systems")
|
||||
public var os = "linux"
|
||||
|
||||
@Option(
|
||||
name: [.long, .short], help: "Set arch if image can target multiple architectures")
|
||||
@Option(name: .shortAndLong, help: "Set arch if image can target multiple architectures")
|
||||
public var arch: String = Arch.hostArchitecture().rawValue
|
||||
|
||||
@Option(name: [.customLong("volume"), .short], help: "Bind mount a volume into the container")
|
||||
public var volumes: [String] = []
|
||||
@Option(name: .long, help: "Write the container ID to the path provided")
|
||||
public var cidfile = ""
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Run the container and detach from the process")
|
||||
public var detach = false
|
||||
|
||||
@Option(
|
||||
name: [.customLong("kernel"), .short], help: "Set a custom kernel path", completion: .file(),
|
||||
name: .customLong("dns"),
|
||||
help: .init("DNS nameserver IP address", valueName: "ip")
|
||||
)
|
||||
public var dnsNameservers: [String] = []
|
||||
|
||||
@Option(
|
||||
name: .long,
|
||||
help: .init("Default DNS domain", valueName: "domain")
|
||||
)
|
||||
public var dnsDomain: String? = nil
|
||||
|
||||
@Option(
|
||||
name: .customLong("dns-option"),
|
||||
help: .init("DNS options", valueName: "option")
|
||||
)
|
||||
public var dnsOptions: [String] = []
|
||||
|
||||
@Option(
|
||||
name: .customLong("dns-search"),
|
||||
help: .init("DNS search domains", valueName: "domain")
|
||||
)
|
||||
public var dnsSearchDomains: [String] = []
|
||||
|
||||
@Option(
|
||||
name: .long,
|
||||
help: .init(
|
||||
"Override the entrypoint of the image",
|
||||
valueName: "cmd"
|
||||
)
|
||||
)
|
||||
public var entrypoint: String?
|
||||
|
||||
@Option(
|
||||
name: .shortAndLong,
|
||||
help: .init("Set a custom kernel path", valueName: "path"),
|
||||
completion: .file(),
|
||||
transform: { str in
|
||||
URL(fileURLWithPath: str, relativeTo: .currentDirectory()).absoluteURL.path(percentEncoded: false)
|
||||
})
|
||||
}
|
||||
)
|
||||
public var kernel: String?
|
||||
|
||||
@Option(name: [.short, .customLong("label")], help: "Add a key=value label to the container")
|
||||
public var labels: [String] = []
|
||||
|
||||
@Option(name: .customLong("mount"), help: "Add a mount to the container (format: type=<>,source=<>,target=<>,readonly)")
|
||||
public var mounts: [String] = []
|
||||
|
||||
@Option(name: .long, help: "Use the specified name as the container ID")
|
||||
public var name: String?
|
||||
|
||||
@Option(name: [.customLong("network")], help: "Attach the container to a network")
|
||||
public var networks: [String] = []
|
||||
|
||||
@Option(name: .customLong("cidfile"), help: "Write the container ID to the path provided")
|
||||
public var cidfile = ""
|
||||
|
||||
@Flag(name: [.customLong("no-dns")], help: "Do not configure DNS in the container")
|
||||
public var dnsDisabled = false
|
||||
|
||||
@Option(name: .customLong("dns"), help: "DNS nameserver IP address")
|
||||
public var dnsNameservers: [String] = []
|
||||
@Option(name: .long, help: "Set OS if image can target multiple operating systems")
|
||||
public var os = "linux"
|
||||
|
||||
@Option(name: .customLong("dns-domain"), help: "Default DNS domain")
|
||||
public var dnsDomain: String? = nil
|
||||
@Option(
|
||||
name: [.customShort("p"), .customLong("publish")],
|
||||
help: .init(
|
||||
"Publish a port from container to host (format: [host-ip:]host-port:container-port[/protocol])",
|
||||
valueName: "spec"
|
||||
)
|
||||
)
|
||||
public var publishPorts: [String] = []
|
||||
|
||||
@Option(name: .customLong("dns-search"), help: "DNS search domains")
|
||||
public var dnsSearchDomains: [String] = []
|
||||
@Option(name: .long, help: "Platform for the image if it's multi-platform. This takes precedence over --os and --arch")
|
||||
public var platform: String?
|
||||
|
||||
@Option(name: .customLong("dns-option"), help: "DNS options")
|
||||
public var dnsOptions: [String] = []
|
||||
@Option(
|
||||
name: .customLong("publish-socket"),
|
||||
help: .init(
|
||||
"Publish a socket from container to host (format: host_path:container_path)",
|
||||
valueName: "spec"
|
||||
)
|
||||
)
|
||||
public var publishSockets: [String] = []
|
||||
|
||||
@Option(name: [.customLong("label"), .short], help: "Add a key=value label to the container")
|
||||
public var labels: [String] = []
|
||||
@Flag(name: [.customLong("rm"), .long], help: "Remove the container after it stops")
|
||||
public var remove = false
|
||||
|
||||
@Flag(name: .long, help: "Forward SSH agent socket to container")
|
||||
public var ssh = false
|
||||
|
||||
@Option(name: .customLong("tmpfs"), help: "Add a tmpfs mount to the container at the given path")
|
||||
public var tmpFs: [String] = []
|
||||
|
||||
@Option(name: [.customLong("volume"), .short], help: "Bind mount a volume into the container")
|
||||
public var volumes: [String] = []
|
||||
|
||||
@Flag(
|
||||
name: [.customLong("virtualization")],
|
||||
name: .long,
|
||||
help:
|
||||
"Expose virtualization capabilities to the container. (Host must have nested virtualization support, and guest kernel must have virtualization capabilities enabled)"
|
||||
"Expose virtualization capabilities to the container (requires host and guest support)"
|
||||
)
|
||||
public var virtualization: Bool = false
|
||||
|
||||
@Flag(name: .customLong("ssh"), help: "Forward SSH agent socket to container")
|
||||
public var ssh = false
|
||||
}
|
||||
|
||||
public struct Progress: ParsableArguments {
|
||||
@@ -170,7 +208,7 @@ public struct Flags {
|
||||
self.disableProgressUpdates = disableProgressUpdates
|
||||
}
|
||||
|
||||
@Flag(name: .customLong("disable-progress-updates"), help: "Disable progress bar updates")
|
||||
@Flag(name: .long, help: "Disable progress bar updates")
|
||||
public var disableProgressUpdates = false
|
||||
}
|
||||
}
|
||||
@@ -192,7 +192,7 @@ public struct Parser {
|
||||
var result: [String] = []
|
||||
var hasEntrypointOverride: Bool = false
|
||||
// ensure the entrypoint is honored if it has been explicitly set by the user
|
||||
if let entrypoint = managementFlags.entryPoint, !entrypoint.isEmpty {
|
||||
if let entrypoint = managementFlags.entrypoint, !entrypoint.isEmpty {
|
||||
result = [entrypoint]
|
||||
hasEntrypointOverride = true
|
||||
} else if let entrypoint = config?.entrypoint, !entrypoint.isEmpty {
|
||||
|
||||
@@ -59,7 +59,7 @@ public struct Application: AsyncParsableCommand {
|
||||
ContainerKill.self,
|
||||
ContainerList.self,
|
||||
ContainerLogs.self,
|
||||
ContainerRunCommand.self,
|
||||
ContainerRun.self,
|
||||
ContainerStart.self,
|
||||
ContainerStop.self,
|
||||
]
|
||||
|
||||
@@ -38,36 +38,18 @@ extension Application {
|
||||
return config
|
||||
}
|
||||
|
||||
@Option(name: [.customLong("cpus"), .customShort("c")], help: "Number of CPUs to allocate to the container")
|
||||
var cpus: Int64 = 2
|
||||
|
||||
@Option(
|
||||
name: [.customLong("memory"), .customShort("m")],
|
||||
help:
|
||||
"Amount of builder container memory (1MiByte granularity), with optional K, M, G, T, or P suffix"
|
||||
name: .shortAndLong,
|
||||
help: ArgumentHelp("Add the architecture type to the build", valueName: "value"),
|
||||
transform: { val in val.split(separator: ",").map { String($0) } }
|
||||
)
|
||||
var memory: String = "2048MB"
|
||||
var arch: [[String]] = {
|
||||
[[Arch.hostArchitecture().rawValue]]
|
||||
}()
|
||||
|
||||
@Option(name: .long, help: ArgumentHelp("Set build-time variables", valueName: "key=val"))
|
||||
var buildArg: [String] = []
|
||||
|
||||
@Argument(help: "Build directory")
|
||||
var contextDir: String = "."
|
||||
|
||||
@Option(name: .shortAndLong, help: ArgumentHelp("Path to Dockerfile", valueName: "path"))
|
||||
var file: String = "Dockerfile"
|
||||
|
||||
@Option(name: .shortAndLong, help: ArgumentHelp("Set a label", valueName: "key=val"))
|
||||
var label: [String] = []
|
||||
|
||||
@Flag(name: .long, help: "Do not use cache")
|
||||
var noCache: Bool = false
|
||||
|
||||
@Option(name: .shortAndLong, help: ArgumentHelp("Output configuration for the build", valueName: "value"))
|
||||
var output: [String] = {
|
||||
["type=oci"]
|
||||
}()
|
||||
|
||||
@Option(name: .long, help: ArgumentHelp("Cache imports for the build", valueName: "value", visibility: .hidden))
|
||||
var cacheIn: [String] = {
|
||||
[]
|
||||
@@ -78,16 +60,33 @@ extension Application {
|
||||
[]
|
||||
}()
|
||||
|
||||
@Option(name: .shortAndLong, help: "Number of CPUs to allocate to the builder container")
|
||||
var cpus: Int64 = 2
|
||||
|
||||
@Option(name: .shortAndLong, help: ArgumentHelp("Path to Dockerfile", valueName: "path"))
|
||||
var file: String = "Dockerfile"
|
||||
|
||||
@Option(name: .shortAndLong, help: ArgumentHelp("Set a label", valueName: "key=val"))
|
||||
var label: [String] = []
|
||||
|
||||
@Option(
|
||||
name: .long,
|
||||
help: "add the platform to the build",
|
||||
transform: { val in val.split(separator: ",").map { String($0) } }
|
||||
name: .shortAndLong,
|
||||
help:
|
||||
"Amount of builder container memory (1MiByte granularity), with optional K, M, G, T, or P suffix"
|
||||
)
|
||||
var platform: [[String]] = [[]]
|
||||
var memory: String = "2048MB"
|
||||
|
||||
@Flag(name: .long, help: "Do not use cache")
|
||||
var noCache: Bool = false
|
||||
|
||||
@Option(name: .shortAndLong, help: ArgumentHelp("Output configuration for the build (format: type=<oci|tar|local>[,dest=])", valueName: "value"))
|
||||
var output: [String] = {
|
||||
["type=oci"]
|
||||
}()
|
||||
|
||||
@Option(
|
||||
name: .long,
|
||||
help: ArgumentHelp("add the OS type to the build", valueName: "value"),
|
||||
help: ArgumentHelp("Add the OS type to the build", valueName: "value"),
|
||||
transform: { val in val.split(separator: ",").map { String($0) } }
|
||||
)
|
||||
var os: [[String]] = {
|
||||
@@ -95,28 +94,29 @@ extension Application {
|
||||
}()
|
||||
|
||||
@Option(
|
||||
name: [.long, .short],
|
||||
help: ArgumentHelp("add the architecture type to the build", valueName: "value"),
|
||||
name: .long,
|
||||
help: "Add the platform to the build (takes precedence over --os and --arch)",
|
||||
transform: { val in val.split(separator: ",").map { String($0) } }
|
||||
)
|
||||
var arch: [[String]] = {
|
||||
[[Arch.hostArchitecture().rawValue]]
|
||||
}()
|
||||
var platform: [[String]] = [[]]
|
||||
|
||||
@Option(name: .long, help: ArgumentHelp("Progress type - one of [auto|plain|tty]", valueName: "type"))
|
||||
@Option(name: .long, help: ArgumentHelp("Progress type (format: auto|plain|tty)]", valueName: "type"))
|
||||
var progress: String = "auto"
|
||||
|
||||
@Option(name: .long, help: ArgumentHelp("Builder-shim vsock port", valueName: "port"))
|
||||
var vsockPort: UInt32 = 8088
|
||||
@Flag(name: .shortAndLong, help: "Suppress build output")
|
||||
var quiet: Bool = false
|
||||
|
||||
@Option(name: [.customShort("t"), .customLong("tag")], help: ArgumentHelp("Name for the built image", valueName: "name"))
|
||||
@Option(name: [.short, .customLong("tag")], help: ArgumentHelp("Name for the built image", valueName: "name"))
|
||||
var targetImageName: String = UUID().uuidString.lowercased()
|
||||
|
||||
@Option(name: .long, help: ArgumentHelp("Set the target build stage", valueName: "stage"))
|
||||
var target: String = ""
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Suppress build output")
|
||||
var quiet: Bool = false
|
||||
@Option(name: .long, help: ArgumentHelp("Builder shim vsock port", valueName: "port"))
|
||||
var vsockPort: UInt32 = 8088
|
||||
|
||||
@Argument(help: "Build directory")
|
||||
var contextDir: String = "."
|
||||
|
||||
public func run() async throws {
|
||||
do {
|
||||
@@ -257,7 +257,7 @@ extension Application {
|
||||
return results
|
||||
}()
|
||||
group.addTask { [terminal, buildArg, contextDir, label, noCache, target, quiet, cacheIn, cacheOut] in
|
||||
let config = ContainerBuild.Builder.BuildConfig(
|
||||
let config = Builder.BuildConfig(
|
||||
buildID: buildID,
|
||||
contentStore: RemoteContentStoreClient(),
|
||||
buildArgs: buildArg,
|
||||
|
||||
@@ -28,27 +28,27 @@ extension Application {
|
||||
commandName: "create",
|
||||
abstract: "Create a new container")
|
||||
|
||||
@OptionGroup(title: "Process options")
|
||||
var processFlags: Flags.Process
|
||||
|
||||
@OptionGroup(title: "Resource options")
|
||||
var resourceFlags: Flags.Resource
|
||||
|
||||
@OptionGroup(title: "Management options")
|
||||
var managementFlags: Flags.Management
|
||||
|
||||
@OptionGroup(title: "Registry options")
|
||||
var registryFlags: Flags.Registry
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Image name")
|
||||
var image: String
|
||||
|
||||
@Argument(parsing: .captureForPassthrough, help: "Container init process arguments")
|
||||
var arguments: [String] = []
|
||||
|
||||
@OptionGroup
|
||||
var processFlags: Flags.Process
|
||||
|
||||
@OptionGroup
|
||||
var resourceFlags: Flags.Resource
|
||||
|
||||
@OptionGroup
|
||||
var managementFlags: Flags.Management
|
||||
|
||||
@OptionGroup
|
||||
var registryFlags: Flags.Registry
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
public func run() async throws {
|
||||
let progressConfig = try ProgressConfig(
|
||||
showTasks: true,
|
||||
|
||||
@@ -28,23 +28,23 @@ extension Application {
|
||||
abstract: "Delete one or more containers",
|
||||
aliases: ["rm"])
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Delete containers even if they are running")
|
||||
var force = false
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Remove all containers")
|
||||
var all = false
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Delete containers even if they are running")
|
||||
var force = false
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Container IDs/names")
|
||||
var containerIDs: [String] = []
|
||||
@Argument(help: "Container IDs")
|
||||
var containerIds: [String] = []
|
||||
|
||||
public func validate() throws {
|
||||
if containerIDs.count == 0 && !all {
|
||||
if containerIds.count == 0 && !all {
|
||||
throw ContainerizationError(.invalidArgument, message: "no containers specified and --all not supplied")
|
||||
}
|
||||
if containerIDs.count > 0 && all {
|
||||
if containerIds.count > 0 && all {
|
||||
throw ContainerizationError(
|
||||
.invalidArgument,
|
||||
message: "explicitly supplied container ID(s) conflict with the --all flag"
|
||||
@@ -53,7 +53,7 @@ extension Application {
|
||||
}
|
||||
|
||||
public mutating func run() async throws {
|
||||
let set = Set<String>(containerIDs)
|
||||
let set = Set<String>(containerIds)
|
||||
var containers = [ClientContainer]()
|
||||
|
||||
if all {
|
||||
|
||||
@@ -28,21 +28,21 @@ extension Application {
|
||||
commandName: "exec",
|
||||
abstract: "Run a new command in a running container")
|
||||
|
||||
@OptionGroup
|
||||
@OptionGroup(title: "Process options")
|
||||
var processFlags: Flags.Process
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Running containers ID")
|
||||
var containerID: String
|
||||
@Argument(help: "Container ID")
|
||||
var containerId: String
|
||||
|
||||
@Argument(parsing: .captureForPassthrough, help: "New process arguments")
|
||||
var arguments: [String]
|
||||
|
||||
public func run() async throws {
|
||||
var exitCode: Int32 = 127
|
||||
let container = try await ClientContainer.get(id: containerID)
|
||||
let container = try await ClientContainer.get(id: containerId)
|
||||
try ensureRunning(container: container)
|
||||
|
||||
let stdin = self.processFlags.interactive
|
||||
|
||||
@@ -30,12 +30,12 @@ extension Application {
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Containers to inspect")
|
||||
var containers: [String]
|
||||
@Argument(help: "Container IDs")
|
||||
var containerIds: [String]
|
||||
|
||||
public func run() async throws {
|
||||
let objects: [any Codable] = try await ClientContainer.list().filter {
|
||||
containers.contains($0.id)
|
||||
containerIds.contains($0.id)
|
||||
}.map {
|
||||
PrintableContainer($0)
|
||||
}
|
||||
|
||||
@@ -26,31 +26,31 @@ extension Application {
|
||||
|
||||
public static let configuration = CommandConfiguration(
|
||||
commandName: "kill",
|
||||
abstract: "Kill one or more running containers")
|
||||
abstract: "Kill or signal one or more running containers")
|
||||
|
||||
@Option(name: .shortAndLong, help: "Signal to send the container(s)")
|
||||
var signal: String = "KILL"
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Kill all running containers")
|
||||
@Flag(name: .shortAndLong, help: "Kill or signal all running containers")
|
||||
var all = false
|
||||
|
||||
@Argument(help: "Container IDs")
|
||||
var containerIDs: [String] = []
|
||||
@Option(name: .shortAndLong, help: "Signal to send to the container(s)")
|
||||
var signal: String = "KILL"
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Container IDs")
|
||||
var containerIds: [String] = []
|
||||
|
||||
public func validate() throws {
|
||||
if containerIDs.count == 0 && !all {
|
||||
if containerIds.count == 0 && !all {
|
||||
throw ContainerizationError(.invalidArgument, message: "no containers specified and --all not supplied")
|
||||
}
|
||||
if containerIDs.count > 0 && all {
|
||||
if containerIds.count > 0 && all {
|
||||
throw ContainerizationError(.invalidArgument, message: "explicitly supplied container IDs conflicts with the --all flag")
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func run() async throws {
|
||||
let set = Set<String>(containerIDs)
|
||||
let set = Set<String>(containerIds)
|
||||
|
||||
var containers = try await ClientContainer.list().filter { c in
|
||||
c.status == .running
|
||||
|
||||
@@ -27,27 +27,27 @@ extension Application {
|
||||
|
||||
public static let configuration = CommandConfiguration(
|
||||
commandName: "logs",
|
||||
abstract: "Fetch container stdio or boot logs"
|
||||
abstract: "Fetch container logs"
|
||||
)
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Follow log output")
|
||||
var follow: Bool = false
|
||||
|
||||
@Flag(name: .long, help: "Display the boot log for the container instead of stdio")
|
||||
var boot: Bool = false
|
||||
|
||||
@Option(name: [.customShort("n")], help: "Number of lines to show from the end of the logs. If not provided this will print all of the logs")
|
||||
@Flag(name: .shortAndLong, help: "Follow log output")
|
||||
var follow: Bool = false
|
||||
|
||||
@Option(name: .short, help: "Number of lines to show from the end of the logs. If not provided this will print all of the logs")
|
||||
var numLines: Int?
|
||||
|
||||
@Argument(help: "Container to fetch logs for")
|
||||
var container: String
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Container ID")
|
||||
var containerId: String
|
||||
|
||||
public func run() async throws {
|
||||
do {
|
||||
let container = try await ClientContainer.get(id: container)
|
||||
let container = try await ClientContainer.get(id: containerId)
|
||||
let fhs = try await container.logs()
|
||||
let fileHandle = boot ? fhs[1] : fhs[0]
|
||||
|
||||
@@ -59,7 +59,7 @@ extension Application {
|
||||
} catch {
|
||||
throw ContainerizationError(
|
||||
.invalidArgument,
|
||||
message: "failed to fetch container logs for \(container): \(error)"
|
||||
message: "failed to fetch container logs for \(containerId): \(error)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -26,30 +26,30 @@ import NIOPosix
|
||||
import TerminalProgress
|
||||
|
||||
extension Application {
|
||||
public struct ContainerRunCommand: AsyncParsableCommand {
|
||||
public struct ContainerRun: AsyncParsableCommand {
|
||||
public init() {}
|
||||
public static let configuration = CommandConfiguration(
|
||||
commandName: "run",
|
||||
abstract: "Run a container")
|
||||
|
||||
@OptionGroup
|
||||
@OptionGroup(title: "Process options")
|
||||
var processFlags: Flags.Process
|
||||
|
||||
@OptionGroup
|
||||
@OptionGroup(title: "Resource options")
|
||||
var resourceFlags: Flags.Resource
|
||||
|
||||
@OptionGroup
|
||||
@OptionGroup(title: "Management options")
|
||||
var managementFlags: Flags.Management
|
||||
|
||||
@OptionGroup
|
||||
@OptionGroup(title: "Registry options")
|
||||
var registryFlags: Flags.Registry
|
||||
|
||||
@OptionGroup(title: "Progress options")
|
||||
var progressFlags: Flags.Progress
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@OptionGroup
|
||||
var progressFlags: Flags.Progress
|
||||
|
||||
@Argument(help: "Image name")
|
||||
var image: String
|
||||
|
||||
@@ -31,14 +31,14 @@ extension Application {
|
||||
@Flag(name: .shortAndLong, help: "Attach STDOUT/STDERR")
|
||||
var attach = false
|
||||
|
||||
@Flag(name: .shortAndLong, help: "Attach container's STDIN")
|
||||
@Flag(name: .shortAndLong, help: "Attach STDIN")
|
||||
var interactive = false
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Container's ID")
|
||||
var containerID: String
|
||||
@Argument(help: "Container ID")
|
||||
var containerId: String
|
||||
|
||||
public func run() async throws {
|
||||
var exitCode: Int32 = 127
|
||||
@@ -52,7 +52,7 @@ extension Application {
|
||||
}
|
||||
progress.start()
|
||||
|
||||
let container = try await ClientContainer.get(id: containerID)
|
||||
let container = try await ClientContainer.get(id: containerId)
|
||||
do {
|
||||
let detach = !self.attach && !self.interactive
|
||||
let io = try ProcessIO.create(
|
||||
@@ -70,7 +70,7 @@ extension Application {
|
||||
if detach {
|
||||
try await process.start()
|
||||
try io.closeAfterStart()
|
||||
print(self.containerID)
|
||||
print(self.containerId)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -31,30 +31,30 @@ extension Application {
|
||||
@Flag(name: .shortAndLong, help: "Stop all running containers")
|
||||
var all = false
|
||||
|
||||
@Option(name: .shortAndLong, help: "Signal to send the container(s)")
|
||||
@Option(name: .shortAndLong, help: "Signal to send the containers")
|
||||
var signal: String = "SIGTERM"
|
||||
|
||||
@Option(name: .shortAndLong, help: "Seconds to wait before killing the container(s)")
|
||||
@Option(name: .shortAndLong, help: "Seconds to wait before killing the containers")
|
||||
var time: Int32 = 5
|
||||
|
||||
@Argument
|
||||
var containerIDs: [String] = []
|
||||
|
||||
@OptionGroup
|
||||
var global: Flags.Global
|
||||
|
||||
@Argument(help: "Container IDs")
|
||||
var containerIds: [String] = []
|
||||
|
||||
public func validate() throws {
|
||||
if containerIDs.count == 0 && !all {
|
||||
if containerIds.count == 0 && !all {
|
||||
throw ContainerizationError(.invalidArgument, message: "no containers specified and --all not supplied")
|
||||
}
|
||||
if containerIDs.count > 0 && all {
|
||||
if containerIds.count > 0 && all {
|
||||
throw ContainerizationError(
|
||||
.invalidArgument, message: "explicitly supplied container IDs conflicts with the --all flag")
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func run() async throws {
|
||||
let set = Set<String>(containerIDs)
|
||||
let set = Set<String>(containerIds)
|
||||
var containers = [ClientContainer]()
|
||||
if self.all {
|
||||
containers = try await ClientContainer.list()
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Copyright © 2025 Apple Inc. and the container 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 ArgumentParser
|
||||
|
||||
extension Application {
|
||||
public struct ContainersCommand: AsyncParsableCommand {
|
||||
public init() {}
|
||||
|
||||
public static let configuration = CommandConfiguration(
|
||||
commandName: "containers",
|
||||
abstract: "Manage containers",
|
||||
subcommands: [
|
||||
ContainerCreate.self,
|
||||
ContainerDelete.self,
|
||||
ContainerExec.self,
|
||||
ContainerInspect.self,
|
||||
ContainerKill.self,
|
||||
ContainerList.self,
|
||||
ContainerLogs.self,
|
||||
ContainerStart.self,
|
||||
ContainerStop.self,
|
||||
],
|
||||
aliases: ["container", "c"]
|
||||
)
|
||||
}
|
||||
}
|
||||
+147
-91
@@ -16,42 +16,47 @@ container run [OPTIONS] IMAGE [COMMAND] [ARG...]
|
||||
|
||||
**Options**
|
||||
|
||||
* **Process and resources**
|
||||
* `-w, --cwd, --workdir <cwd>`: Current working directory for the container
|
||||
* `-e, --env <env>`: Set environment variables
|
||||
* `--env-file <env-file>`: Read in a file of environment variables
|
||||
* `--uid <uid>`: Set the uid for the process
|
||||
* `--gid <gid>`: Set the gid for the process
|
||||
* `-i, --interactive`: Keep Stdin open even if not attached
|
||||
* `-t, --tty`: Open a tty with the process
|
||||
* `-u, --user <user>`: Set the user for the process
|
||||
* **Process options**
|
||||
* `-e, --env <env>`: Set environment variables (format: key=value)
|
||||
* `--env-file <env-file>`: Read in a file of environment variables (key=value format, ignores # comments and blank lines)
|
||||
* `--gid <gid>`: Set the group ID for the process
|
||||
* `-i, --interactive`: Keep the standard input open even if not attached
|
||||
* `-t, --tty`: Open a TTY with the process
|
||||
* `-u, --user <user>`: Set the user for the process (format: name|uid[:gid])
|
||||
* `--uid <uid>`: Set the user ID for the process
|
||||
* `-w, --workdir, --cwd <dir>`: Set the initial working directory inside the container
|
||||
* **Resource options**
|
||||
* `-c, --cpus <cpus>`: Number of CPUs to allocate to the container
|
||||
* `-m, --memory <memory>`: Amount of memory in bytes, kilobytes (K), megabytes (M), or gigabytes (G) for the container, with MB granularity (for example, 1024K will result in 1MB being allocated for the container)
|
||||
* **Container management**
|
||||
* `-d, --detach`: Run the container and detach from the process
|
||||
* `--entrypoint <entrypoint>`: Override the entrypoint of the image
|
||||
* `--mount <mount>`: Add a mount to the container (type=<>,source=<>,target=<>,readonly)
|
||||
* `-p, --publish <publish>`: Publish a port from container to host (format: [host-ip:]host-port:container-port[/protocol])
|
||||
* `--publish-socket <publish-socket>`: Publish a socket from container to host (format: host_path:container_path)
|
||||
* `--tmpfs <tmpfs>`: Add a tmpfs mount to the container at the given path
|
||||
* `--name <name>`: Assign a name to the container. If excluded will be a generated UUID
|
||||
* `--remove, --rm`: Remove the container after it stops
|
||||
* `--os <os>`: Set OS if image can target multiple operating systems (default: linux)
|
||||
* `-m, --memory <memory>`: Amount of memory (1MiByte granularity), with optional K, M, G, T, or P suffix
|
||||
* **Management options**
|
||||
* `-a, --arch <arch>`: Set arch if image can target multiple architectures (default: arm64)
|
||||
* `-v, --volume <volume>`: Bind mount a volume into the container
|
||||
* `-k, --kernel <kernel>`: Set a custom kernel path
|
||||
* `--network <network>`: Attach the container to a network
|
||||
* `--cidfile <cidfile>`: Write the container ID to the path provided
|
||||
* `--no-dns`: Do not configure DNS in the container
|
||||
* `--dns <dns>`: DNS nameserver IP address
|
||||
* `--dns-domain <dns-domain>`: Default DNS domain
|
||||
* `--dns-search <dns-search>`: DNS search domains
|
||||
* `--dns-option <dns-option>`: DNS options
|
||||
* `-d, --detach`: Run the container and detach from the process
|
||||
* `--dns <ip>`: DNS nameserver IP address
|
||||
* `--dns-domain <domain>`: Default DNS domain
|
||||
* `--dns-option <option>`: DNS options
|
||||
* `--dns-search <domain>`: DNS search domains
|
||||
* `--entrypoint <cmd>`: Override the entrypoint of the image
|
||||
* `-k, --kernel <path>`: Set a custom kernel path
|
||||
* `-l, --label <label>`: Add a key=value label to the container
|
||||
* `--virtualization`: Expose virtualization capabilities to the container. (Host must have nested virtualization support, and guest kernel must have virtualization capabilities enabled)
|
||||
* **Registry/progress/global**
|
||||
* `--scheme <scheme>`: Scheme to use when connecting to the container registry. One of (`http`, `https`, `auto`) (default: `auto`)
|
||||
* `--mount <mount>`: Add a mount to the container (format: type=<>,source=<>,target=<>,readonly)
|
||||
* `--name <name>`: Use the specified name as the container ID
|
||||
* `--network <network>`: Attach the container to a network
|
||||
* `--no-dns`: Do not configure DNS in the container
|
||||
* `--os <os>`: Set OS if image can target multiple operating systems (default: linux)
|
||||
* `-p, --publish <spec>`: Publish a port from container to host (format: [host-ip:]host-port:container-port[/protocol])
|
||||
* `--platform <platform>`: Platform for the image if it's multi-platform. This takes precedence over --os and --arch
|
||||
* `--publish-socket <spec>`: Publish a socket from container to host (format: host_path:container_path)
|
||||
* `--rm, --remove`: Remove the container after it stops
|
||||
* `--ssh`: Forward SSH agent socket to container
|
||||
* `--tmpfs <tmpfs>`: Add a tmpfs mount to the container at the given path
|
||||
* `-v, --volume <volume>`: Bind mount a volume into the container
|
||||
* `--virtualization`: Expose virtualization capabilities to the container (requires host and guest support)
|
||||
* **Registry options**
|
||||
* `--scheme <scheme>`: Scheme to use when connecting to the container registry. One of (http, https, auto) (default: auto)
|
||||
* **Progress options**
|
||||
* `--disable-progress-updates`: Disable progress bar updates
|
||||
* **Global options**
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
@@ -76,31 +81,32 @@ Builds an OCI image from a local build context. It reads a Dockerfile (default `
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container build [OPTIONS] PATH
|
||||
container build [OPTIONS] [CONTEXT-DIR]
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `CONTEXT-DIR`: Build directory (default: .)
|
||||
|
||||
**Options**
|
||||
|
||||
* **Resource management**
|
||||
* `-c, --cpus <number>`: CPUs to allocate to the build process (default 2)
|
||||
* `-m, --memory <size>`: Amount of memory in bytes, kilobytes (K), megabytes (M), or gigabytes (G) for the container, with MB granularity (for example, 1024K will result in 1MB being allocated for the container) (default: 2048MB)
|
||||
* **Build configuration**
|
||||
* `--build-arg <key=value>`: build-time variables passed to the Dockerfile
|
||||
* `-f, --file <path>`: path to the Dockerfile (default `Dockerfile`)
|
||||
* `-l, --label <key=value>`: add metadata labels to the image
|
||||
* `--no-cache`: disable cache usage
|
||||
* `-o, --output <config>`: specify build output (default `type=oci`)
|
||||
* `--arch <arch>`: target architecture (default `arm64`)
|
||||
* `--os <os>`: target operating system (default `linux`)
|
||||
* `--progress <type>`: progress output mode: `auto`, `plain`, or `tty`
|
||||
* `--vsock-port <port>`: Builder-shim vsock port (default 8088)
|
||||
* `-t, --tag <name>`: set image name and tag
|
||||
* `--target <stage>`: set the target stage for multi-stage builds
|
||||
* `-q, --quiet`: suppress build output
|
||||
* **Global**
|
||||
* `--debug`: enable debug logging
|
||||
* `--version`: show version and exit
|
||||
* `-h, --help`: show help
|
||||
* `-a, --arch <value>`: Add the architecture type to the build
|
||||
* `--build-arg <key=val>`: Set build-time variables
|
||||
* `-c, --cpus <cpus>`: Number of CPUs to allocate to the builder container (default: 2)
|
||||
* `-f, --file <path>`: Path to Dockerfile (default: Dockerfile)
|
||||
* `-l, --label <key=val>`: Set a label
|
||||
* `-m, --memory <memory>`: Amount of builder container memory (1MiByte granularity), with optional K, M, G, T, or P suffix (default: 2048MB)
|
||||
* `--no-cache`: Do not use cache
|
||||
* `-o, --output <value>`: Output configuration for the build (format: type=<oci|tar|local>[,dest=]) (default: type=oci)
|
||||
* `--os <value>`: Add the OS type to the build
|
||||
* `--platform <platform>`: Add the platform to the build (takes precedence over --os and --arch)
|
||||
* `--progress <type>`: Progress type (format: auto|plain|tty)] (default: auto)
|
||||
* `-q, --quiet`: Suppress build output
|
||||
* `-t, --tag <name>`: Name for the built image
|
||||
* `--target <stage>`: Set the target build stage
|
||||
* `--vsock-port <port>`: Builder shim vsock port (default: 8088)
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
**Examples**
|
||||
|
||||
@@ -139,14 +145,20 @@ Starts a stopped container. You can attach to the container's output streams and
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container start [OPTIONS] CONTAINER
|
||||
container start [OPTIONS] CONTAINER-ID
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `CONTAINER-ID`: Container ID
|
||||
|
||||
**Options**
|
||||
|
||||
* `-a, --attach`: attach to STDOUT/STDERR of the container
|
||||
* `-i, --interactive`: attach STDIN for interactive sessions
|
||||
* **Global**: `--debug`, `--version`, `-h`/`--help`
|
||||
* `-a, --attach`: Attach STDOUT/STDERR
|
||||
* `-i, --interactive`: Attach STDIN
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
### `container stop`
|
||||
|
||||
@@ -155,31 +167,43 @@ Stops running containers gracefully by sending a signal. A timeout can be specif
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container stop [OPTIONS] [CONTAINER...]
|
||||
container stop [OPTIONS] [CONTAINER-IDS...]
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `CONTAINER-IDS`: Container IDs
|
||||
|
||||
**Options**
|
||||
|
||||
* `-a, --all`: stop all running containers
|
||||
* `-s, --signal <signal>`: signal to send (default SIGTERM)
|
||||
* `-t, --time <seconds>`: timeout in seconds before killing the container (default 5)
|
||||
* **Global**: `--debug`, `--version`, `-h`/`--help`
|
||||
* `-a, --all`: Stop all running containers
|
||||
* `-s, --signal <signal>`: Signal to send the containers (default: SIGTERM)
|
||||
* `-t, --time <time>`: Seconds to wait before killing the containers (default: 5)
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
### `container kill`
|
||||
|
||||
Immediately kills running containers by sending a signal (defaults to `SIGKILL`). Use with caution: it does not allow for graceful shutdown.
|
||||
Immediately kills running containers by sending a signal (defaults to `KILL`). Use with caution: it does not allow for graceful shutdown.
|
||||
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container kill [OPTIONS] [CONTAINER...]
|
||||
container kill [OPTIONS] [CONTAINER-IDS...]
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `CONTAINER-IDS`: Container IDs
|
||||
|
||||
**Options**
|
||||
|
||||
* `-s, --signal <signal>`: signal to send (default `KILL`)
|
||||
* `-a, --all`: kill all running containers
|
||||
* **Global**: `--debug`, `--version`, `-h`/`--help`
|
||||
* `-a, --all`: Kill or signal all running containers
|
||||
* `-s, --signal <signal>`: Signal to send to the container(s) (default: KILL)
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
### `container delete (rm)`
|
||||
|
||||
@@ -188,14 +212,20 @@ Removes one or more containers. If the container is running, you may force delet
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container delete [OPTIONS] [CONTAINER...]
|
||||
container delete [OPTIONS] [CONTAINER-IDS...]
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `CONTAINER-IDS`: Container IDs
|
||||
|
||||
**Options**
|
||||
|
||||
* `-f, --force`: remove running containers by sending SIGKILL
|
||||
* `-a, --all`: remove all containers
|
||||
* **Global**: `--debug`, `--version`, `-h`/`--help`
|
||||
* `-a, --all`: Remove all containers
|
||||
* `-f, --force`: Force the removal of one or more running containers
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
### `container list (ls)`
|
||||
|
||||
@@ -209,10 +239,12 @@ container list [OPTIONS]
|
||||
|
||||
**Options**
|
||||
|
||||
* `-a, --all`: include stopped containers
|
||||
* `-q, --quiet`: display only container IDs
|
||||
* `--format <format>`: Format of the output (values: `json`, `table`; default: `table`)
|
||||
* **Global**: `--debug`, `--version`, `-h`/`--help`
|
||||
* `-a, --all`: Show stopped containers as well
|
||||
* `--format <format>`: Format of the output (values: json, table; default: table)
|
||||
* `-q, --quiet`: Only output the container ID
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
### `container exec`
|
||||
|
||||
@@ -221,20 +253,30 @@ Executes a command inside a running container. It uses the same process flags as
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container exec [OPTIONS] CONTAINER COMMAND [ARG...]
|
||||
container exec [OPTIONS] CONTAINER-ID ARGUMENTS...
|
||||
```
|
||||
|
||||
**Key flags**
|
||||
**Arguments**
|
||||
|
||||
* `-w, --cwd, --workdir <cwd>`: Current working directory for the container
|
||||
* `-e, --env <env>`: Set environment variables
|
||||
* `--env-file <env-file>`: Read in a file of environment variables
|
||||
* `--uid <uid>`: Set the uid for the process
|
||||
* `--gid <gid>`: Set the gid for the process
|
||||
* `-i, --interactive`: Keep Stdin open even if not attached
|
||||
* `-t, --tty`: Open a tty with the process
|
||||
* `-u, --user <user>`: Set the user for the process
|
||||
* **Global**: `--debug`, `--version`, `-h`/`--help`
|
||||
* `CONTAINER-ID`: Container ID
|
||||
* `ARGUMENTS`: New process arguments
|
||||
|
||||
**Process flags**
|
||||
|
||||
* `-e, --env <env>`: Set environment variables (format: key=value)
|
||||
* `--env-file <env-file>`: Read in a file of environment variables (key=value format, ignores # comments and blank lines)
|
||||
* `--gid <gid>`: Set the group ID for the process
|
||||
* `-i, --interactive`: Keep the standard input open even if not attached
|
||||
* `-t, --tty`: Open a TTY with the process
|
||||
* `-u, --user <user>`: Set the user for the process (format: name|uid[:gid])
|
||||
* `--uid <uid>`: Set the user ID for the process
|
||||
* `-w, --workdir, --cwd <dir>`: Set the initial working directory inside the container
|
||||
|
||||
**Options**
|
||||
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
### `container logs`
|
||||
|
||||
@@ -243,15 +285,21 @@ Fetches logs from a container. You can follow the logs (`-f`/`--follow`), restri
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container logs [OPTIONS] CONTAINER
|
||||
container logs [OPTIONS] CONTAINER-ID
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
* `CONTAINER-ID`: Container ID
|
||||
|
||||
**Options**
|
||||
|
||||
* `-f, --follow`: Follow log output
|
||||
* `--boot`: Display the boot log for the container instead of stdio
|
||||
* `-n <lines>`: Number of lines to show from the end of the logs. If not provided this will print all of the logs
|
||||
* **Global**: `--debug`, `--version`, `-h`/`--help`
|
||||
* `-f, --follow`: Follow log output
|
||||
* `-n <n>`: Number of lines to show from the end of the logs. If not provided this will print all of the logs
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
### `container inspect`
|
||||
|
||||
@@ -260,10 +308,18 @@ Displays detailed container information in JSON. Pass one or more container IDs
|
||||
**Usage**
|
||||
|
||||
```bash
|
||||
container inspect [OPTIONS] CONTAINER...
|
||||
container inspect [OPTIONS] CONTAINER-IDS...
|
||||
```
|
||||
|
||||
No additional flags; uses global flags for debug, version, and help.
|
||||
**Arguments**
|
||||
|
||||
* `CONTAINER-IDS`: Container IDs
|
||||
|
||||
**Options**
|
||||
|
||||
* `--debug`: Enable debug output [environment: CONTAINER_DEBUG]
|
||||
* `--version`: Show the version.
|
||||
* `-h, --help`: Show help information.
|
||||
|
||||
## Image Management
|
||||
|
||||
|
||||
Reference in new issue
Block a user