Skip to content
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

Add WithVolumeMountForData #1317

Conversation

stbau04
Copy link
Contributor

@stbau04 stbau04 commented Dec 9, 2023

Make it easier to use external volumes for database containers:

  • Added WithVolumeFor.../WithBindMountFor... for data, logs and init folders
    • For the data directory on all containers
    • For the logs directory on containers with logs enabled by default (as it might confuse if the WithVolumeForLogs is available but log files are not actually enabled in the container configuration)
    • For the init folder where a /docker-entrypoint-initdb.d folder is avilable (did not find something similar on the other containers)

Fixes #837

Microsoft Reviewers: Open in CodeFlow

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-codeflow for labeling automated codeflow. intentionally a different color! label Dec 9, 2023
@DamianEdwards
Copy link
Member

Thanks for this. We should add overloads of this method that support the other database container resources too, with the appropriate path in those cases.

@stbau04
Copy link
Contributor Author

stbau04 commented Dec 11, 2023

Before adding the others i would wait for the discussion on the issue (#837 (comment)). If this is still the approch we stick too i will continue adding the overloads.

@joperezr joperezr added the community-contribution Indicates that the PR has been added by a community member label Dec 11, 2023
@stbau04 stbau04 force-pushed the stbau04/make-it-easier-to-use-external-volumes-for-database-containers branch from 223216d to 3a22a40 Compare December 16, 2023 22:00
@stbau04 stbau04 marked this pull request as ready for review January 4, 2024 18:27
@stbau04
Copy link
Contributor Author

stbau04 commented Jan 4, 2024

@josephaw1022 created a second (duplicate) PR for this one: #1447

@stbau04
Copy link
Contributor Author

stbau04 commented Jan 7, 2024

Probably we should wait for #1521 and then see how it affects this pr (especially the volume/bind mount stuff)

@mitchdenny mitchdenny self-assigned this Jan 10, 2024
@danmoseley danmoseley added area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication and removed area-codeflow for labeling automated codeflow. intentionally a different color! labels Feb 6, 2024
@davidfowl
Copy link
Member

@stbau04 Would you like to resurrect this PR?

@davidfowl
Copy link
Member

@DamianEdwards wdyt?

@DamianEdwards
Copy link
Member

@davidfowl yeah I like this a lot actually. @stbau04 if you're around it would be great if you could update this for changes since Dec (mainly the split out of WithBindMount and WithVolume from WithVolumeMount), otherwise I'm happy to take this over for preview.5

@stbau04
Copy link
Contributor Author

stbau04 commented Mar 4, 2024

@davidfowl @DamianEdwards Yes sure, i'll update it

@davidfowl
Copy link
Member

I'm gonna assign this to you @stbau04. Thanks!

@stbau04 stbau04 marked this pull request as draft March 4, 2024 16:23
@stbau04
Copy link
Contributor Author

stbau04 commented Mar 4, 2024

There are the following container resources that might support some of the methods (the checked ones are implemented):
RabbitMQServerResource ✅
MySqlServerResource ✅
PostgresServerResource ✅
MongoDBServerResource ✅
RedisResource ✅
SqlServerServerResource ✅
KafkaServerResource
MongoExpressContainerResource
PhpMyAdminContainerResource
OracleDatabaseServerResource
PgAdminContainerResource
RedisCommandResource
AzureCosmosDbEmulatorResource
AzureStorageEmulatorResource

@DamianEdwards
Copy link
Member

Seems you did a merge instead of a rebase so this PR is showing up as including all changes on main since you originally created it! Can you go back to before you merged and do a rebase on main instead, and then force push to your fork/branch?

@davidfowl
Copy link
Member

davidfowl commented Mar 5, 2024

@DamianEdwards @mitchdenny Do we want to align here with the UsePersistance calls

public static IResourceBuilder<AzureStorageEmulatorResource> UsePersistence(this IResourceBuilder<AzureStorageEmulatorResource> builder, string? path = null)
{
path = path ?? $".azurite/{builder.Resource.Name}";
var fullyQualifiedPath = Path.GetFullPath(path, builder.ApplicationBuilder.AppHostDirectory);
return builder.WithBindMount(fullyQualifiedPath, "/data", isReadOnly: false);
?

Feels like we should have a consistent pattern. The above picks a default name as well.

@mitchdenny
Copy link
Member

I'm not sure I like the interfaces in this PR. It seems to me that persistence for each container is a fairly container specific thing and we might want to have a specific extension method for each container. Perhaps in that case the overload takes a basePath and then if the container supports init/log/data directories then a bindmount is applied for each one relative to the base path.

@mitchdenny
Copy link
Member

Thinking about this some more, I think what we want here is a per container type extension that takes into consideration the various quirks assocaited with each container. So instead of a pattern that would seem people doing this:

builder.AddRedis("redis").WithBindMountForLogs(path).WithBindMountForInit(path).WithBindMountForData(path)

We could just do this:

builder.AddRedis("redis").WithPersistence(path);

The benefit is that it is a simpler gesture for the consumer of the container and it allows us to abstract away wierdness that some containers might have. For example, the Cosmos container which we use for the emulator doesn't seem to work with bind mounts -- so this mechanism wouldn't work. Instead for that we'd need to implement a WithPersistence(...) method which computes a unique volume name and use that instead of a bind mount.

So in summary ... its good to make it easy for people to turn on persistence for a given container (we should do that!) but lets not make it generic when it probably isn't because we have to live with this abstraction for a while ;)

@DamianEdwards
Copy link
Member

I think we need more than a single method if for no other reason than to support bind mounts vs. volumes. Perhaps it's just two overloads (one accepting a path and another not) but I think that's less clear than the proposed methods. Personally not a fan of the WithPersistance naming generally.

@DamianEdwards
Copy link
Member

DamianEdwards commented Mar 5, 2024

Perhaps a simple change to WithDataVolume and WithDataBindMount, etc. for these. The interface approach seems fine for now I think? What kind of thing would trip that approach up?

@stbau04 stbau04 force-pushed the stbau04/make-it-easier-to-use-external-volumes-for-database-containers branch from db89bd9 to d896322 Compare March 5, 2024 17:06
@DamianEdwards
Copy link
Member

DamianEdwards commented Mar 6, 2024

To address @mitchdenny's concerns here I think a good compromise would be to get rid of the interfaces and just establish a pattern for these kind of container-based resources by adding methods like WithDataVolume and WithDataBindMount where they support it. If a particular container image has quirks beyond just needing to know the path to mount the volume or bind mount to, it can be handled in that method.

For init and logs, I think it only makes sense to have support for bind mounts for init, and both volume and bind mounts for logs. Reasoning being that init is all about an input to the container (run these scripts) whereas data and logs are potentially input and output.

In the case of volumes, we should support auto-generating a name based on the resource name or specifying a name.

So we'd end up with methods like the following on the relevant container-based resources:

  • WithDataVolume(string? name = null)
  • WithLogsVolume(string? name = null)
  • WithDataBindMount(string source)
  • WithLogsBindMount(string source)
  • WithInitBindMount(string source)

Open question is whether we should support auto-generating a source location for the bind mount methods (like the azurite one does). I'm not particularly fussed on that, could take it or leave it. Perhaps we leave it for now and can always add it later.

@DamianEdwards
Copy link
Member

@stbau04 are you able to update your approach here to what I described above?

@stbau04
Copy link
Contributor Author

stbau04 commented Mar 8, 2024

@DamianEdwards Yes sure

@stbau04
Copy link
Contributor Author

stbau04 commented Mar 8, 2024

Is that the desired approach we should follow?

@DamianEdwards
Copy link
Member

Is that the desired approach we should follow?

That is what I'm currently proposing, Would be good to explicitly hear from @mitchdenny if he has any concerns with that approach.

@stbau04
Copy link
Contributor Author

stbau04 commented Mar 9, 2024

@DamianEdwards @mitchdenny I've applied the proposed approach to the first few containers. If you are fine with this solution i would continue implementing it for the remaining resources. Do you have any imput for me?

Especially what about the naming for the volumes, is the default name ok like that? If we keep it as it is, you cannot run a project twice on the same host - or have resources with the same name in different projects - if you want to use the auto-generated name. Are we fine with that?

src/Aspire.Hosting/MongoDB/MongoDBBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/MongoDB/MongoDBBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/MongoDB/MongoDBBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/MongoDB/MongoDBBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/MongoDB/MongoDBBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/MySql/MySqlBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/Postgres/PostgresBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/RabbitMQ/RabbitMQBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/Redis/RedisBuilderExtensions.cs Outdated Show resolved Hide resolved
src/Aspire.Hosting/SqlServer/SqlServerBuilderExtensions.cs Outdated Show resolved Hide resolved
@dotnet-policy-service dotnet-policy-service bot added needs-author-action An issue or pull request that requires more info or actions from the author. and removed needs-author-action An issue or pull request that requires more info or actions from the author. labels Mar 9, 2024
@DamianEdwards
Copy link
Member

@stbau04 thanks for the updates! Were there more resource types you were planning to apply this pattern to?

@davidfowl
Copy link
Member

I would leave the azure resources as they are currently being renovated by @mitchdenny. @mitchdenny you can take this pattern to the existing emulators.

@DamianEdwards
Copy link
Member

@stbau04 I think this is ready to review now?

@stbau04
Copy link
Contributor Author

stbau04 commented Mar 9, 2024

@DamianEdwards I could maybe add some methods for the following: KafkaServerResource, MongoExpressContainerResource, PhpMyAdminContainerResource, OracleDatabaseServerResource, PgAdminContainerResource and RedisCommandResource (might take me some time to figure out the correct paths)
If this is not necessary/wantend at the moment it would be ready to review

@davidfowl
Copy link
Member

KafkaServerResource - 👍🏾
OracleDatabaseServerResource - 👍🏾

The rest I would skip.

@stbau04
Copy link
Contributor Author

stbau04 commented Mar 10, 2024

@DamianEdwards I've added some method for the KafkaServer and OracleDatabaseServer resoures. I think it should be ready for review now

@stbau04 stbau04 marked this pull request as ready for review March 10, 2024 18:43
@stbau04 stbau04 requested a review from DamianEdwards March 10, 2024 18:43
@davidfowl
Copy link
Member

@mitchdenny We need to change cosmos and azure storage to use the same pattern yes? WithVolumeForData?

@davidfowl
Copy link
Member

Seq differs a little here:

string? seqDataDirectory = null)

We should make this follow the same pattern I think.

@davidfowl
Copy link
Member

It can be a follow up though

@davidfowl davidfowl merged commit 9817678 into dotnet:main Mar 11, 2024
8 checks passed
@davidfowl
Copy link
Member

Thanks @stbau04 !!!!

@github-actions github-actions bot locked and limited conversation to collaborators Apr 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make it easier to use external volumes for database containers
6 participants