Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Move to TOML configuration for defaults - #1425

Merged
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config
May 4, 2026
Merged

Move to TOML configuration for defaults#1425
jglogan merged 3 commits into
apple:mainfrom
noah-thor:toml-runtime-config

Conversation

@noah-thor

@noah-thornoah-thor commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This change migrates away from using UserDefaults, instead providing a TOML configuration mechanism for user configurable settings. All exisitng features of user configurability are maintained. However, users will have to migrate any settings they have configured in the UserDefaults into TOML for these settings to take effect.

Breaking changes:

  • container system property get is removed in favor of users directly utilizing container system property list --format toml | jq<>.
  • container system property set is removed since the TOML configuration is effectively immutable during the lifetime of the container daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via container system stop && container system start
  • container system property list --format table is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable

Addresses discussion (#1336)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Context within #1336

We're looking to improve the user experience and overall functionality of setting defaults for container to better enable future use cases.

Today container uses macOS's UserDefaults to configure settings needed at runtime. As mentioned in #608, UserDefaults may be idiomatic for macOS, but they apply globally to all sessions and do not handle representing complex, hierarchical data well. Additionally, we currently have two ways of setting these defaults, either directly with macOS's defaults command or through container system property.

#608 proposes moving to use environment variables in place of UserDefaults. However, we do not believe this is sufficient. Environment variables are not in a consistent location, are not sourced from data, and also do not handle representing complex, hierarchical data well.

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation cli labels Apr 16, 2026
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift Outdated
static let listenAddress = "127.0.0.1"
static let localhostDNSPort = 1053
static let dnsPort = 2053
private static let containerSystemConfig: ContainerSystemConfig = try! SystemRuntimeOptions.loadConfig(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: force unwraps are generally unsafe, I would not use try!

@manojmahapatramanojmahapatraApr 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, containerSystemConfig is being repeated at many places, in addition to I'm seeing every function that needs config accepts it as a parameter, and every function that calls those functions also accepts, even if it doesn't use the config itself. I think we can do better/different by not passing around into the chain of functions, but hoist it up as a higher level @Environment kinda property.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@manojmahapatra As an alternative to the current approach in this PR, we also considered having a service on APIServer that managed defaults. We decided against this for a few reasons: we want to avoid services needing to call back to APIServer unless absolutely necessary and we believe configurations values should not change during the lifetime of a service instance (with some rare exceptions). That said, we're still discussing how we want to extend the current approach to allow for user level overrides, such as with environment variables.

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC are you implying to have some kind of runtime (immutable) context and inject that at module boundaries? (eg SystemStart)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I would prefer. But we do still want to support some user level overrides, so how to make that experience nice is still an open question. What do you think?

@manojmahapatramanojmahapatraApr 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, thanks for clarifying. I think explicit user overrides are the right direction; probably the other open question is what would be the precedence order. (we need to define that)

So, a reasonable approach could be then to add a single central config resolver that builds a final config with an explicit order?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming we support user overrides with a file and with environment variables, I think the precedence would be environment variables -> user overrides file -> system config. The issue with environment variables is that they can change over the lifetime of container so we can't just read them once to create the final config :/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that definitely had crossed my mind, unless we bubble up some kind of hot reloading of config file on demand. I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@jgloganjgloganApr 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure if this is the right direction or hot reloading of config file even makes sense.

@manojmahapatra Agree...I think it's "we aren't going to need it today". We can start simple and try not to paint ourselves into a corner and evolve from there.

We can move slowly on env variables as well. Here's a rough snapshot of what we have right now:

NAMEWHERENOTES
CONTAINER_{APP,INSTALL,LOG}_ROOTservicesplumbed from system start args into launchd.plist files, no TOML config needed
CONTAINER_DEBUGCLIcommands check --debug, then this
CONTAINER_DEBUG_LAUNCHD_LABELservicesplumbed into apiserver environment at system start, see #1101, no TOML config needed
CONTAINER_DEFAULT_PLATFORMCLIsimilar to DOCKER_DEFAULT_PLATFORM, TOML configuration could also make sense here but not immediately required
CONTAINER_REGISTRY_{HOST,TOKEN,USER}servicesplumbed into apiserver environment at system start, used for limited cases only, no TOML config needed

None of these require TOML config today, so we can treat them as orthogonal for now.

As far as our existing properties go, none today have environment overrides AFAIK, so we can decide later if say, we want to be able to do something like export CONTAINER_MEMORY=8g in one shell session and have container run evaluate --memory, then CONTAINER_MEMORY, then the user TOML, then the system TOML.

Comment threadSources/ContainerPersistence/ContainerSystemConfig.swift
Comment threadSources/Services/ContainerAPIService/Client/ClientImage.swift Outdated
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

I addressed all ongoing discussions as part of this commit. I also noticed that the Measurement swift type does not play very nicely with the TOMLEncoder in terms of human readability, so added a small wrapper around that type to fix the ux.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit. Will resolve conflicts once everything else looks good.

New revision changes a few things:

  • Removes container system property get <> in favor of recommending users leverage container system property list --format json | jq <>
  • Removes container system property list --format table as maintaining a table format was not simple, and the new toml format is a suitable replacement for human readers.

@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Pushed new commit:

  • fixed issue with DNSConfig providing a "test" default changing behavior of request scheme
  • removed static force unwraps in favor of a try let in run()
  • rebased

Comment threaddocs/how-to.md Outdated
Comment threaddocs/tutorial.md Outdated
}

final public class KernelConfig: Codable, Sendable {
public static let defaultBinaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there only a user TOML file for this PR, and no system TOML that we include in our distribution?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, there is only one TOML that lives in users home

Comment threaddocs/tutorial.md Outdated
Comment threadBUILDING.md Outdated
```bash
container system property set image.init vminit:latest
```toml
[image]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this if we do restructure.

Comment threadBUILDING.md Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/Services/ContainerAPIService/Client/RequestScheme.swift Outdated
Comment threadSources/ContainerPersistence/MemorySize.swift
Comment threadSources/ContainerPersistence/MemorySize.swift

private let log = Logger(label: "SystemRuntimeOptions")

/// TOML-backed configuration loader.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how it works?

  • container system start copies the config to the application root so that the API server and any service plugins is spawns have a consistent system view
  • CLI commands use the same application root config, such that the user would need to stop/start the container service if they wanted to make a change to a setting that impacts CLI command behavior

Comment threadSources/ContainerBuild/BuildPipelineHandler.swift Outdated
Comment threadSources/ContainerCommands/Builder/BuilderStart.swift
Comment threadSources/Services/ContainerNetworkService/Server/ReservedVmnetNetwork.swift Outdated
let defaultKernelURL = kernelDependency.source
let defaultKernelBinaryPath = DefaultsStore.get(key: .defaultKernelBinaryPath)

private func installDefaultKernel(kernelURL: URL, kernelBinaryPath: String) async throws {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really installDefaultKernel() anymore? It just installs a kernel.

This change migrates away from using `UserDefaults`, instead providing a
TOML configuration mechanism for user configurable settings. Users will
have to migrate any custom defaults configured via `UserDefaults` into a
toml configuration file in `~/.config/container/`.
- Addresses discussion apple#1336
@jgloganjglogan added this to the 2026-05 milestone Apr 25, 2026
@jgloganjglogan added the ux User experience features and fixes. label Apr 25, 2026
@noah-thor

Copy link
Copy Markdown
ContributorAuthor

Merged from main to update PR

@jglogan
jglogan merged commit e3c4980 into apple:mainMay 4, 2026
3 checks passed
noah-thor added a commit to noah-thor/container that referenced this pull request May 6, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: #1425).
katiewasnothere pushed a commit that referenced this pull request May 8, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.

@karaday411-sketchkaraday411-sketch left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R

@noah-thor
noah-thor deleted the toml-runtime-config branch July 22, 2026 17:33
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
- Discussion topic apple#1336.
- This change migrates away from using `UserDefaults`,
instead providing a TOML configuration mechanism for
user configurable settings. All existing system property
settings keys are supported in the new configuration
file. However, users will have to migrate any settings
they have configured in the `UserDefaults` into TOML
for these settings to take effect.
- Breaking changes:
* `container system property get` is removed in favor of
users directly utilizing `container system property list --format toml | jq<>`.
* `container system property set` is removed since the TOML
configuration is effectively immutable during the lifetime of the
`container` daemon. Uses can edit the TOML they have in their home
directory, however no changes will take effect until the daemon is
restarted via `container system stop && container system start`
* `container system property list --format table` is removed as
generating tabular format is non-trivial and the new TOML format is
intended to be human readable
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
…e#1448)
This creates a more centralized utility to find and load configuration files, as a follow up to (pr: apple#1425).
jianliang00 pushed a commit to jianliang00/container that referenced this pull request Aug 28, 2026
This adds a swift Decoder that decodes from a swift-configuration
ConfigSnapshot, and adds the ability to modify how select types are
decoded within the
ConfigSnapshotDecoder. This is something that JSONEncoder already does
with URLs specifically, however this enables users to configure this
behavior for any arbitrary type regardless of existing Codable
conformance.
The decoder will help us expand on top of (pr:
apple#1425), which switches user
configuration to TOML. With this PR we will be able to provide a multi
layered TOML if desired, allowing container to ship a default TOML
instead of encoding them in code constants.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clidocumentationImprovements or additions to documentationuxUser experience features and fixes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@noah-thor@jglogan@manojmahapatra@katiewasnothere@karaday411-sketch@JaewonHur