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 WithPgWeb #5098

Merged
merged 21 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 9 additions & 18 deletions Aspire.sln
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Containers.Tests", "tests\Aspire.Hosting.Containers.Tests\Aspire.Hosting.Containers.Tests.csproj", "{588CD2D7-EE70-43C1-8233-330854BDF53C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WithDockerfile.AppHost", "playground\withdockerfile\WithDockerfile.AppHost\WithDockerfile.AppHost.csproj", "{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Elastic.Clients.Elasticsearch.Tests", "tests\Aspire.Elastic.Clients.Elasticsearch.Tests\Aspire.Elastic.Clients.Elasticsearch.Tests.csproj", "{D5B392A4-29CD-41F9-8847-0C211C832713}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "python", "python", "{7123AB7A-A4FD-4F64-8B05-D2DD0C3E2ABC}"
Expand All @@ -526,7 +527,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.PostgreSQL.T
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Qdrant.Tests", "tests\Aspire.Hosting.Qdrant.Tests\Aspire.Hosting.Qdrant.Tests.csproj", "{8E2AA85E-C351-47B4-AF91-58557FAD5840}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.Hosting.Milvus.Tests", "tests\Aspire.Hosting.Milvus.Tests\Aspire.Hosting.Milvus.Tests.csproj", "{986886B7-0E38-4890-92C3-5B46DE322DAF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Milvus.Tests", "tests\Aspire.Hosting.Milvus.Tests\Aspire.Hosting.Milvus.Tests.csproj", "{986886B7-0E38-4890-92C3-5B46DE322DAF}"
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.MySql.Tests", "tests\Aspire.Hosting.MySql.Tests\Aspire.Hosting.MySql.Tests.csproj", "{F3F33CF8-A2BB-4351-8501-A6884C5126FE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Kafka.Tests", "tests\Aspire.Hosting.Kafka.Tests\Aspire.Hosting.Kafka.Tests.csproj", "{0A83AA67-221E-44B4-9BA9-DC64DC17949E}"
Expand Down Expand Up @@ -1369,10 +1371,6 @@ Global
{569B8215-BDB1-445D-A7BA-DB255700A4AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{569B8215-BDB1-445D-A7BA-DB255700A4AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{569B8215-BDB1-445D-A7BA-DB255700A4AC}.Release|Any CPU.Build.0 = Release|Any CPU
{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9}.Release|Any CPU.Build.0 = Release|Any CPU
{588CD2D7-EE70-43C1-8233-330854BDF53C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{588CD2D7-EE70-43C1-8233-330854BDF53C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{588CD2D7-EE70-43C1-8233-330854BDF53C}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -1397,14 +1395,6 @@ Global
{1BC02557-B78B-48CE-9D3C-488A6B7672F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1BC02557-B78B-48CE-9D3C-488A6B7672F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BC02557-B78B-48CE-9D3C-488A6B7672F4}.Release|Any CPU.Build.0 = Release|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.Build.0 = Release|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Release|Any CPU.Build.0 = Release|Any CPU
{7425E5B2-BC47-4521-AC40-B8CECA329E08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7425E5B2-BC47-4521-AC40-B8CECA329E08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7425E5B2-BC47-4521-AC40-B8CECA329E08}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -1413,6 +1403,10 @@ Global
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E2AA85E-C351-47B4-AF91-58557FAD5840}.Release|Any CPU.Build.0 = Release|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{986886B7-0E38-4890-92C3-5B46DE322DAF}.Release|Any CPU.Build.0 = Release|Any CPU
{F3F33CF8-A2BB-4351-8501-A6884C5126FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3F33CF8-A2BB-4351-8501-A6884C5126FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3F33CF8-A2BB-4351-8501-A6884C5126FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -1692,27 +1686,24 @@ Global
{9FAE1602-2C69-4D24-8655-A164489441E8} = {C424395C-1235-41A4-BF55-07880A04368C}
{DF00FDA3-D3EC-4E07-B4EC-0EBB57A813A4} = {77CFE74A-32EE-400C-8930-5025E8555256}
{5CB63205-24F4-4388-A41B-BAF3BEA59866} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47}
{588CD2D7-EE70-43C1-8233-330854BDF53C} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
{9357EC71-823B-433A-9993-B7CB2FA082D1} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47}
{3F7B206E-5457-458F-AA81-9449FA3C1B5C} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2}
{6C71A90C-30AE-45D7-9347-D66F9B257CBE} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
{F7F57331-5DDD-444A-A620-8639FC9362B2} = {6C71A90C-30AE-45D7-9347-D66F9B257CBE}
{569B8215-BDB1-445D-A7BA-DB255700A4AC} = {6C71A90C-30AE-45D7-9347-D66F9B257CBE}
{A6813855-E322-41EF-B2E6-7A44949EF962} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9} = {A6813855-E322-41EF-B2E6-7A44949EF962}
{588CD2D7-EE70-43C1-8233-330854BDF53C} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{E6BE41D3-872C-47D2-B5B1-78C37AFAEAF9} = {A6813855-E322-41EF-B2E6-7A44949EF962}
{D5B392A4-29CD-41F9-8847-0C211C832713} = {C424395C-1235-41A4-BF55-07880A04368C}
{7123AB7A-A4FD-4F64-8B05-D2DD0C3E2ABC} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
{173BDA6E-F175-4457-BF64-58CD184E9A81} = {7123AB7A-A4FD-4F64-8B05-D2DD0C3E2ABC}
{62D8C73C-DAB3-4B9E-A508-34C886C374F9} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{C424395C-1235-41A4-BF55-07880A04368C} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
{830A89EC-4029-4753-B25A-068BAE37DEC7} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
{1BC02557-B78B-48CE-9D3C-488A6B7672F4} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{8E2AA85E-C351-47B4-AF91-58557FAD5840} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{986886B7-0E38-4890-92C3-5B46DE322DAF} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{7425E5B2-BC47-4521-AC40-B8CECA329E08} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{8E2AA85E-C351-47B4-AF91-58557FAD5840} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{986886B7-0E38-4890-92C3-5B46DE322DAF} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{F3F33CF8-A2BB-4351-8501-A6884C5126FE} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{0A83AA67-221E-44B4-9BA9-DC64DC17949E} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
{72F5A6F3-3516-402B-8F8D-50A7BC2E4BD4} = {830A89EC-4029-4753-B25A-068BAE37DEC7}
Expand Down
11 changes: 10 additions & 1 deletion playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
// External resources.
var db10 = builder.AddPostgres("pg10").WithPgAdmin().PublishAsConnectionString().AddDatabase("db10");

builder.Configuration["Parameters:pass"] = "p!ssw0rd1";
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved

var pass = builder.AddParameter("pass");

var db11 = builder.AddPostgres("pg11",password: pass).AddDatabase("postgres").WithPgWeb();
var db12 = builder.AddPostgres("pg12").AddDatabase("db12").WithPgWeb();

builder.AddProject<Projects.PostgresEndToEnd_ApiService>("api")
.WithExternalHttpEndpoints()
.WithReference(db1)
Expand All @@ -32,7 +39,9 @@
.WithReference(db7)
.WithReference(db8)
.WithReference(db9)
.WithReference(db10);
.WithReference(db10)
.WithReference(db11)
.WithReference(db12);

// This project is only added in playground projects to support development/debugging
// of the dashboard. It is not required in end developer code. Comment out this code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,52 @@
"type": "value.v0",
"connectionString": "{pg10.connectionString};Database=db10"
},
"pg11": {
"type": "container.v0",
"connectionString": "Host={pg11.bindings.tcp.host};Port={pg11.bindings.tcp.port};Username=postgres;Password={pg11-password.value}",
"image": "docker.io/library/postgres:16.2",
"env": {
"POSTGRES_HOST_AUTH_METHOD": "scram-sha-256",
"POSTGRES_INITDB_ARGS": "--auth-host=scram-sha-256 --auth-local=scram-sha-256",
"POSTGRES_USER": "postgres",
"POSTGRES_PASSWORD": "{pg11-password.value}"
},
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 5432
}
}
},
"db11": {
"type": "value.v0",
"connectionString": "{pg11.connectionString};Database=db11"
},
"pg12": {
"type": "container.v0",
"connectionString": "Host={pg12.bindings.tcp.host};Port={pg12.bindings.tcp.port};Username=postgres;Password={pg12-password.value}",
"image": "docker.io/library/postgres:16.2",
"env": {
"POSTGRES_HOST_AUTH_METHOD": "scram-sha-256",
"POSTGRES_INITDB_ARGS": "--auth-host=scram-sha-256 --auth-local=scram-sha-256",
"POSTGRES_USER": "postgres",
"POSTGRES_PASSWORD": "{pg12-password.value}"
},
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 5432
}
}
},
"db12": {
"type": "value.v0",
"connectionString": "{pg12.connectionString};Database=db12"
},
"api": {
"type": "project.v0",
"path": "../PostgresEndToEnd.ApiService/PostgresEndToEnd.ApiService.csproj",
Expand All @@ -184,7 +230,9 @@
"ConnectionStrings__db7": "{db7.connectionString}",
"ConnectionStrings__db8": "{db8.connectionString}",
"ConnectionStrings__db9": "{db9.connectionString}",
"ConnectionStrings__db10": "{db10.connectionString}"
"ConnectionStrings__db10": "{db10.connectionString}",
"ConnectionStrings__db11": "{db11.connectionString}",
"ConnectionStrings__db12": "{db12.connectionString}"
},
"bindings": {
"http": {
Expand Down Expand Up @@ -290,6 +338,36 @@
}
}
}
},
"pg11-password": {
"type": "parameter.v0",
"value": "{pg11-password.inputs.value}",
"inputs": {
"value": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 22
}
}
}
}
},
"pg12-password": {
"type": "parameter.v0",
"value": "{pg12-password.inputs.value}",
"inputs": {
"value": {
"type": "string",
"secret": true,
"default": {
"generate": {
"minLength": 22
}
}
}
}
}
}
}
1 change: 1 addition & 0 deletions spelling.dic
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ upsert
uris
urls
kubernetes
Pgweb
42 changes: 42 additions & 0 deletions src/Aspire.Hosting.PostgreSQL/PgAdminConfigWriterHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,45 @@ public Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, C
return Task.CompletedTask;
}
}

internal sealed class PgWebConfigWriterHook : IDistributedApplicationLifecycleHook
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
{
public Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken)
{
var adminResource = appModel.Resources.OfType<PgWebContainerResource>().Single();
var serverFileMount = adminResource.Annotations.OfType<ContainerMountAnnotation>().Single(v => v.Target == "/.pgweb/bookmarks");
var postgresInstances = appModel.Resources.OfType<PostgresDatabaseResource>();

var serverFileBuilder = new StringBuilder();



// Need to grant read access to the config file on unix like systems.
if (!OperatingSystem.IsWindows())
{
File.SetUnixFileMode(serverFileMount.Source!, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.OtherRead);
}

foreach (var postgresDatabase in postgresInstances)
{
var user = postgresDatabase.Parent.UserNameParameter?.Value ?? "postgres";

var fileContent = $"""
host = "{postgresDatabase.Parent.PrimaryEndpoint.Host}"
port = {postgresDatabase.Parent.PrimaryEndpoint.Port}
user = "{user}"
database = "{postgresDatabase.DatabaseName}"
sslmode = "require"
""";

if (!Directory.Exists(serverFileMount.Source!))
{
Directory.CreateDirectory(serverFileMount.Source!);
}
var filePath = Path.Combine(serverFileMount.Source!, $"{postgresDatabase.Name}.toml");
File.WriteAllText(filePath, fileContent);
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
}

return Task.CompletedTask;
}
}
15 changes: 15 additions & 0 deletions src/Aspire.Hosting.PostgreSQL/PgWebContainerResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Aspire.Hosting.ApplicationModel;

namespace Aspire.Hosting.Postgres;

/// <summary>
/// Represents a container resource for pgweb.
/// </summary>
/// <param name="name">The name of the container resource.</param>
public sealed class PgWebContainerResource(string name) : ContainerResource(name)
{

}
67 changes: 67 additions & 0 deletions src/Aspire.Hosting.PostgreSQL/PostgresBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,73 @@ public static IResourceBuilder<PgAdminContainerResource> WithHostPort(this IReso
});
}

/// <summary>
/// Configures the host port that the pgweb resource is exposed on instead of using randomly assigned port.
/// </summary>
/// <param name="builder">The resource builder for pgweb.</param>
/// <param name="port">The port to bind on the host. If <see langword="null"/> is used random port will be assigned.</param>
/// <returns>The resource builder for pgweb.</returns>
public static IResourceBuilder<PgWebContainerResource> WithHostPort(this IResourceBuilder<PgWebContainerResource> builder, int? port)
{
return builder.WithEndpoint("http", endpoint =>
{
endpoint.Port = port;
});
}

/// <summary>
/// Adds an administration and development platform for PostgreSQL to the application model using pgweb. This version the package defaults to the 2.3-latest tag of the latest container image
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <example>
/// Use in application host with a Postgres resource
/// <code lang="csharp">
/// var builder = DistributedApplication.CreateBuilder(args);
///
/// var postgres = builder.AddPostgres("postgres");
/// var db = postgres.AddDatabase("db")
/// .WithPgWeb();
/// var api = builder.AddProject&lt;Projects.Api&gt;("api")
/// .WithReference(db);
///
/// builder.Build().Run();
/// </code>
/// </example>
/// <param name="builder">The Postgres server resource builder.</param>
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
/// <param name="configureContainer">Configuration callback for pgweb container resource.</param>
/// <param name="containerName">The name of the container (Optional).</param>
/// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>
public static IResourceBuilder<T> WithPgWeb<T>(this IResourceBuilder<T> builder, Action<IResourceBuilder<PgWebContainerResource>>? configureContainer = null, string? containerName = null) where T : PostgresDatabaseResource
{

if (builder.ApplicationBuilder.Resources.OfType<PgWebContainerResource>().SingleOrDefault() is { } existingPgAdminResource)
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
{
var builderForExistingResource = builder.ApplicationBuilder.CreateResourceBuilder(existingPgAdminResource);
configureContainer?.Invoke(builderForExistingResource);
return builder;
}
else
{
builder.ApplicationBuilder.Services.TryAddLifecycleHook<PgWebConfigWriterHook>();

containerName ??= $"{builder.Resource.Name}-pgweb";
var dir = Directory.CreateTempSubdirectory().FullName;
Copy link
Member

Choose a reason for hiding this comment

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

How does this directory get cleaned up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

do we have a hook or event when a resource stopped/finished?

I think we should add one API for that in IDistributedApplicationLifecycleHook

Copy link
Member

Choose a reason for hiding this comment

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

This is actually a problem right now. @karolz-ms interested in your thoughts here. We sometimes drop temporary files in disk and I'd like to be able to try and ensure that they are cleaned up. We can probably have some kind of temporary file register that goes and does clean up but its highly likely that some of those files/directories are going to be locked because things like containers are spinning down.

This might be one of those things that DCP could help with?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think DCP would be a good place for logic that deals with "cleanup" tasks like removing temporary log files.

There are probably many ways to do this, but the simplest one that will work today, is to put them inside the DCP session folder (which the app host runtime knows about). That folder is automatically deleted when DCP is shutting down. Just make sure the name is reasonably unique when creating the file.

Copy link
Member

Choose a reason for hiding this comment

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

(we might be missing an API for the extensions that will tell them what the "temporary folder for the current application run" is)

Copy link
Member

Choose a reason for hiding this comment

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

We could do that too. Feel free to open an issue and we can add it to our backlog for DCP.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what is our approach for cleanup temp files for this PR?

Copy link
Member

Choose a reason for hiding this comment

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

@mitchdenny - would this be a good usage of the new Eventing API? We could have an event that fires when the resource is shut down.

Copy link
Member

Choose a reason for hiding this comment

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

what is our approach for cleanup temp files for this PR?

Since we already have the same issue with pgadmin:

.WithBindMount(Path.GetTempFileName(), "/pgadmin4/servers.json")
.ExcludeFromManifest();
builder.ApplicationBuilder.Eventing.Subscribe<AfterEndpointsAllocatedEvent>((e, ct) =>
{
var serverFileMount = pgAdminContainer.Annotations.OfType<ContainerMountAnnotation>().Single(v => v.Target == "/pgadmin4/servers.json");
var postgresInstances = builder.ApplicationBuilder.Resources.OfType<PostgresServerResource>();
var serverFileBuilder = new StringBuilder();
using var stream = new FileStream(serverFileMount.Source!, FileMode.Create);

I'd be fine with continuing here to just create temp files and leave them, for now, until we get the clean up capability.

Copy link
Member

Choose a reason for hiding this comment

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

Yes ... although it wouldn't be 100%. If someone kills the process via the debugger (most common scenario) I don't think we guarantee that this is run. But better than nothing I guess.

Console.WriteLine("pgweg bookmars {0}", dir);
var pgwebContainer = new PgWebContainerResource(containerName);
var pgwebContainerBuilder = builder.ApplicationBuilder.AddResource(pgwebContainer)
.WithImage(PostgresContainerImageTags.PgwebImage, PostgresContainerImageTags.PgwebTag)
.WithImageRegistry(PostgresContainerImageTags.PgwebRegistry)
.WithHttpEndpoint(targetPort: 8081, name: "http")
.WithBindMount(dir, "/.pgweb/bookmarks")
.WithArgs("--bookmarks-dir=/.pgweb/bookmarks")
.WithArgs("--sessions")
.ExcludeFromManifest();

configureContainer?.Invoke(pgwebContainerBuilder);
return builder;

Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
}
}

private static void SetPgAdminEnvironmentVariables(EnvironmentCallbackContext context)
{
// Disables pgAdmin authentication.
Expand Down
3 changes: 3 additions & 0 deletions src/Aspire.Hosting.PostgreSQL/PostgresContainerImageTags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ internal static class PostgresContainerImageTags
public const string PgAdminRegistry = "docker.io";
public const string PgAdminImage = "dpage/pgadmin4";
public const string PgAdminTag = "8.8";
public const string PgwebRegistry = "docker.io";
Alirexaa marked this conversation as resolved.
Show resolved Hide resolved
public const string PgwebImage = "sosedoff/pgweb";
public const string PgwebTag = "latest";
}
5 changes: 4 additions & 1 deletion src/Aspire.Hosting.PostgreSQL/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
#nullable enable

Aspire.Hosting.Postgres.PgWebContainerResource
Aspire.Hosting.Postgres.PgWebContainerResource.PgWebContainerResource(string! name) -> void
static Aspire.Hosting.PostgresBuilderExtensions.WithHostPort(this Aspire.Hosting.ApplicationModel.IResourceBuilder<Aspire.Hosting.Postgres.PgWebContainerResource!>! builder, int? port) -> Aspire.Hosting.ApplicationModel.IResourceBuilder<Aspire.Hosting.Postgres.PgWebContainerResource!>!
static Aspire.Hosting.PostgresBuilderExtensions.WithPgWeb<T>(this Aspire.Hosting.ApplicationModel.IResourceBuilder<T!>! builder, System.Action<Aspire.Hosting.ApplicationModel.IResourceBuilder<Aspire.Hosting.Postgres.PgWebContainerResource!>!>? configureContainer = null, string? containerName = null) -> Aspire.Hosting.ApplicationModel.IResourceBuilder<T!>!