-
Notifications
You must be signed in to change notification settings - Fork 618
Add support for copying existing files via WithContainerFiles API #8908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for copying existing files via the WithContainerFiles API, replacing the previous bind mount mechanism for realm imports in Keycloak.
- Updated tests to validate the new ContainerFileSystemCallbackAnnotation functionality via asynchronous execution.
- Modified the Container model to enforce that file entries use either SourcePath or Contents but not both.
- Updated the KeycloakResourceBuilderExtensions to utilize the WithContainerFiles API using new C# 12 collection patterns.
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
File | Description |
---|---|
tests/Aspire.Hosting.Keycloak.Tests/KeycloakPublicApiTests.cs | Updated test methods to async, altered assertions to verify ContainerFileSystemCallbackAnnotation usage. |
src/Aspire.Hosting/Dcp/Model/Container.cs | Added Source assignment from SourcePath and mutual exclusion check between Contents and SourcePath. |
src/Aspire.Hosting/ApplicationModel/ContainerFileSystemCallbackAnnotation.cs | Updated documentation for ContainerFile to clarify mutual exclusion semantics between Contents and SourcePath. |
src/Aspire.Hosting/Keycloak/KeycloakResourceBuilderExtensions.cs | Switched from WithBindMount to WithContainerFiles using new collection initialization syntax. |
Comments suppressed due to low confidence (1)
tests/Aspire.Hosting.Keycloak.Tests/KeycloakPublicApiTests.cs:224
- The variable 'file' is used in the assertion but is not defined anywhere in the test. Consider defining it (e.g., var file = Path.GetFileName(filePath);) before using it in assertions.
Assert.Equal(file, realmFile.Name);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No bind mount 😍
/// </summary> | ||
public string? Contents { get; set; } | ||
|
||
/// <summary> | ||
/// The path to a file on the host system to copy into the container. This path must be absolute and point to a file on the host system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does the path need to be absolute? We can use relative paths elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don’t explicitly check for an absolute path; it’s more of a SHOULD requirement. We can’t necessarily guarantee the orchestrator and container runtime will have the correct working directory in all scenarios, so absolute paths guarantees consistent behavior. We probably should call out the same for the bind mount annotation.
Are there any direct tests that can be added for this functionality? If we ever deleted Keycloak (unlikely) we wouldn't have any coverage. |
src/Aspire.Hosting.Keycloak/KeycloakResourceBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
This would mitigate some of the bind mount issues in #7078, but there's implications for the generated manifest in switching from bind mount to WithContainerFiles. |
This could be supported in the compose publish targets via the configs feature. One undocumented part of the compose configs spec is that you can specify the content inline and they'll be copied in the same way we do in WithContainerFiles. |
I say we move this to 9.4 |
configs: | ||
- source: "cache__usr_local_share_redis.conf" | ||
target: "/usr/local/share/redis.conf" | ||
mode: 0644 | ||
- source: "cache__usr_local_share_folder_file.sh" | ||
target: "/usr/local/share/folder/file.sh" | ||
uid: 1000 | ||
gid: 1000 | ||
mode: 0700 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is VERY cool 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was definitely happy to find out compose configs can support basically the full set of configuration from WithContainerFiles. Makes having a consistent runtime and publish experience a lot easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spoke too soon; there is one headache in that compose will ignore uid, gid, and mode when using source file mode (vs specifying inline content). They use a volume when a specific file is referenced, but cp
when contents are provided.
One option would be to simply read text and convert every referenced file to the inline content form, but that wouldn't work if a user was expecting to use WithContainerFiles for a binary file.
@@ -123,6 +140,41 @@ private async Task WriteDockerComposeOutputAsync(DistributedApplicationModel mod | |||
envFile.Save(envFilePath); | |||
} | |||
|
|||
private static void HandleComposeFileConfig(ComposeFile composeFile, Service composeService, ContainerFileSystemItem? item, int? uid, int? gid, UnixFileMode umask, string path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to copy files to the output folder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated to copy source files into a subdirectory of the OutputPath named after the service they belong to (so <OutputPath>/<ServiceName>/<FileName>
). I'm using a relative path to when generating the compose file to make it portable.
All good? |
@davidfowl yeah, there’s one annoyance with compose ignoring permissions and ownership settings when giving a source file (vs inline contents), but otherwise everything is working as expected. We can’t fix that permissions behavior (it’s a compose bug that others have by, but we may be able to workaround it. I’m inclined to tackle that in a separate PR though. |
Description
Adds the ability to specify an existing file via
WithContainerFiles
instead of having to specify the contents of a file. Uses the same permission mechanics and slots into the existing ability to create arbitrary files and folders. Specifically, aContainerFile
type passed toWithContainerFiles
can take either aContents
property orSourcePath
property (an exception will be thrown if both are set).Fixes #5498
Checklist
<remarks />
and<code />
elements on your triple slash comments?doc-idea
templatebreaking-change
templatediagnostic
template