-
Notifications
You must be signed in to change notification settings - Fork 668
[containers]: add system-start flag for auto-start of containers #1201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,10 +20,13 @@ import ContainerPersistence | |
| import ContainerPlugin | ||
| import ContainerizationError | ||
| import Foundation | ||
| import Logging | ||
| import TerminalProgress | ||
|
|
||
| extension Application { | ||
| public struct SystemStart: AsyncLoggableCommand { | ||
| private static let startTimeoutSeconds: Int32 = 5 | ||
|
|
||
| public static let configuration = CommandConfiguration( | ||
| commandName: "start", | ||
| abstract: "Start `container` services" | ||
|
|
@@ -53,6 +56,14 @@ extension Application { | |
| public init() {} | ||
|
|
||
| public func run() async throws { | ||
| // TODO: update this to use the new logger | ||
| let log = Logger( | ||
| label: "com.apple.container.cli", | ||
| factory: { label in | ||
| StreamLogHandler.standardOutput(label: label) | ||
| } | ||
| ) | ||
|
|
||
| // Without the true path to the binary in the plist, `container-apiserver` won't launch properly. | ||
| // TODO: Can we use the plugin loader to bootstrap the API server? | ||
| let executableUrl = CommandLine.executablePathUrl | ||
|
|
@@ -104,10 +115,56 @@ extension Application { | |
| try? await installInitialFilesystem() | ||
| } | ||
|
|
||
| guard await !kernelExists() else { | ||
| return | ||
| if await !kernelExists() { | ||
| try? await installDefaultKernel() | ||
| } | ||
|
|
||
| // Start all the containers that have system-start enabled | ||
| log.info("starting containers", metadata: ["startTimeoutSeconds": "\(Self.startTimeoutSeconds)"]) | ||
| try await startContainers() | ||
| } | ||
|
|
||
| /// Starts all containers that are configured to automatically start on system start. | ||
| /// | ||
| /// - Throws: `AggregateError` containing all errors encountered during container startup. | ||
| private func startContainers() async throws { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might be able to move starting containers to the API server, near
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can take a look at this but
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh got it. We need to change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NVM this comment, I was testing AI based PR review yesterday and it corrupted my brain :) |
||
| let client = ContainerClient() | ||
| let containers = try await client.list() | ||
| let systemStartContainers = containers.filter { $0.createOptions?.systemStart == true && $0.status != .running } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. either or in this case |
||
| var errors: [any Error] = [] | ||
|
|
||
| await withTaskGroup(of: (any Error)?.self) { group in | ||
| for container in systemStartContainers { | ||
| group.addTask { | ||
| do { | ||
| let io = try ProcessIO.create( | ||
| tty: container.configuration.initProcess.terminal, | ||
| interactive: false, | ||
| detach: true | ||
| ) | ||
| defer { try? io.close() } | ||
|
|
||
| let process = try await client.bootstrap(id: container.id, stdio: io.stdio) | ||
| try await process.start() | ||
| try io.closeAfterStart() | ||
| print(container.id) | ||
| return nil | ||
| } catch { | ||
| return error | ||
| } | ||
| } | ||
| } | ||
|
|
||
| for await error in group { | ||
| if let error { | ||
| errors.append(error) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if !errors.isEmpty { | ||
| throw AggregateError(errors) | ||
| } | ||
| try await installDefaultKernel() | ||
| } | ||
|
|
||
| private func installInitialFilesystem() async throws { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,11 +16,13 @@ | |
|
|
||
| public struct ContainerCreateOptions: Codable, Sendable { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| public let autoRemove: Bool | ||
| public let systemStart: Bool | ||
|
|
||
| public init(autoRemove: Bool) { | ||
| public init(autoRemove: Bool, systemStart: Bool) { | ||
| self.autoRemove = autoRemove | ||
| self.systemStart = systemStart | ||
| } | ||
|
|
||
| public static let `default` = ContainerCreateOptions(autoRemove: false) | ||
| public static let `default` = ContainerCreateOptions(autoRemove: false, systemStart: false) | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -230,6 +230,12 @@ public struct Flags { | |
|
|
||
| @Option(name: .long, help: "Set the runtime handler for the container (default: container-runtime-linux)") | ||
| public var runtime: String? | ||
|
|
||
| @Flag( | ||
| name: .customLong("systemstart"), | ||
| help: "Automatically start the container when the container system starts" | ||
| ) | ||
| public var systemStart: Bool = false | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I neglected to use |
||
| } | ||
|
|
||
| public struct Progress: ParsableArguments { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,6 +68,7 @@ container run [<options>] <image> [<arguments> ...] | |
| * `-v, --volume <volume>`: Bind mount a volume into the container | ||
| * `--virtualization`: Expose virtualization capabilities to the container (requires host and guest support) | ||
| * `--runtime`: Set the runtime handler for the container (default: container-runtime-linux) | ||
| * `--systemstart`: Automatically start the container when the container system starts | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. Will make that change before this gets merged. |
||
|
|
||
| **Registry Options** | ||
|
|
||
|
|
@@ -223,6 +224,7 @@ container create [<options>] <image> [<arguments> ...] | |
| * `-v, --volume <volume>`: Bind mount a volume into the container | ||
| * `--virtualization`: Expose virtualization capabilities to the container (requires host and guest support) | ||
| * `--runtime`: Set the runtime handler for the container (default: container-runtime-linux) | ||
| * `--systemstart`: Automatically start the container when the container system starts | ||
|
|
||
| **Registry Options** | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it's the best to print "SYSTEM-START" here..
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was mulling on the idea of adding this to the print output. I feel users should have the ability to know if a container will be started automatically on system startup. It might be worthwhile adding a
--verboseoption (like image list), where this field will be added to the output (default output will not included it).