Skip to content

Commit 0cc7553

Browse files
sebastienrosdanmoseley
authored andcommitted
Optimize required unix file modes (#7781)
1 parent adb706d commit 0cc7553

File tree

24 files changed

+336
-201
lines changed

24 files changed

+336
-201
lines changed

playground/PostgresEndToEnd/PostgresEndToEnd.AppHost/PostgresEndToEnd.AppHost.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
<IsAspireHost>true</IsAspireHost>
9+
<UserSecretsId>f8cd0caa-3990-4f6f-889f-3cf66ac52de9</UserSecretsId>
910
</PropertyGroup>
1011

1112
<ItemGroup>

playground/mysql/MySqlDb.AppHost/MySqlDb.AppHost.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
<IsAspireHost>true</IsAspireHost>
9+
<UserSecretsId>7359b387-0386-4cd0-9f26-7b40bdb8348d</UserSecretsId>
910
</PropertyGroup>
1011

1112
<ItemGroup>

src/Aspire.Hosting.Azure.EventHubs/AzureEventHubsExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ namespace Aspire.Hosting;
1919
/// </summary>
2020
public static class AzureEventHubsExtensions
2121
{
22+
private const UnixFileMode FileMode644 = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.OtherRead;
23+
2224
/// <summary>
2325
/// Adds an Azure Event Hubs Namespace resource to the application model. This resource can be used to create Event Hub resources.
2426
/// </summary>
@@ -325,10 +327,7 @@ public static IResourceBuilder<AzureEventHubsResource> RunAsEmulator(this IResou
325327
// The docker container runs as a non-root user, so we need to grant other user's read/write permission
326328
if (!OperatingSystem.IsWindows())
327329
{
328-
var mode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute |
329-
UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute;
330-
331-
File.SetUnixFileMode(configJsonPath, mode);
330+
File.SetUnixFileMode(configJsonPath, FileMode644);
332331
}
333332

334333
builder.WithAnnotation(new ContainerMountAnnotation(
@@ -434,6 +433,7 @@ public static IResourceBuilder<AzureEventHubsEmulatorResource> WithConfiguration
434433

435434
private static string WriteEmulatorConfigJson(AzureEventHubsResource emulatorResource)
436435
{
436+
// This temporary file is not used by the container, it will be copied and then deleted
437437
var filePath = Path.GetTempFileName();
438438

439439
using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Write);

src/Aspire.Hosting.Azure.ServiceBus/AzureServiceBusExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ namespace Aspire.Hosting;
2020
/// </summary>
2121
public static class AzureServiceBusExtensions
2222
{
23+
private const UnixFileMode FileMode644 = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.OtherRead;
24+
2325
/// <summary>
2426
/// Adds an Azure Service Bus Namespace resource to the application model. This resource can be used to create queue, topic, and subscription resources.
2527
/// </summary>
@@ -426,10 +428,7 @@ public static IResourceBuilder<AzureServiceBusResource> RunAsEmulator(this IReso
426428
// The docker container runs as a non-root user, so we need to grant other user's read/write permission
427429
if (!OperatingSystem.IsWindows())
428430
{
429-
var mode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute |
430-
UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute;
431-
432-
File.SetUnixFileMode(configJsonPath, mode);
431+
File.SetUnixFileMode(configJsonPath, FileMode644);
433432
}
434433

435434
builder.WithAnnotation(new ContainerMountAnnotation(
@@ -559,6 +558,7 @@ public static IResourceBuilder<AzureServiceBusEmulatorResource> WithHostPort(thi
559558

560559
private static string WriteEmulatorConfigJson(AzureServiceBusResource emulatorResource)
561560
{
561+
// This temporary file is not used by the container, it will be copied and then deleted
562562
var filePath = Path.GetTempFileName();
563563

564564
using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Write);

src/Aspire.Hosting.MySql/MySqlBuilderExtensions.cs

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace Aspire.Hosting;
1414
public static class MySqlBuilderExtensions
1515
{
1616
private const string PasswordEnvVarName = "MYSQL_ROOT_PASSWORD";
17+
private const UnixFileMode FileMode644 = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead | UnixFileMode.OtherRead;
1718

1819
/// <summary>
1920
/// Adds a MySQL server resource to the application model. For local development a container is used.
@@ -102,14 +103,11 @@ public static IResourceBuilder<T> WithPhpMyAdmin<T>(this IResourceBuilder<T> bui
102103

103104
containerName ??= $"{builder.Resource.Name}-phpmyadmin";
104105

105-
var configurationTempFileName = Path.GetTempFileName();
106-
107106
var phpMyAdminContainer = new PhpMyAdminContainerResource(containerName);
108107
var phpMyAdminContainerBuilder = builder.ApplicationBuilder.AddResource(phpMyAdminContainer)
109108
.WithImage(MySqlContainerImageTags.PhpMyAdminImage, MySqlContainerImageTags.PhpMyAdminTag)
110109
.WithImageRegistry(MySqlContainerImageTags.Registry)
111110
.WithHttpEndpoint(targetPort: 80, name: "http")
112-
.WithBindMount(configurationTempFileName, "/etc/phpmyadmin/config.user.inc.php")
113111
.ExcludeFromManifest();
114112

115113
builder.ApplicationBuilder.Eventing.Subscribe<AfterEndpointsAllocatedEvent>((e, ct) =>
@@ -140,32 +138,33 @@ public static IResourceBuilder<T> WithPhpMyAdmin<T>(this IResourceBuilder<T> bui
140138
}
141139
else
142140
{
143-
using var stream = new FileStream(configurationTempFileName, FileMode.Create);
144-
using var writer = new StreamWriter(stream);
141+
var tempConfigFile = WritePhpMyAdminConfiguration(mySqlInstances);
145142

146-
writer.WriteLine("<?php");
147-
writer.WriteLine();
148-
writer.WriteLine("$i = 0;");
149-
writer.WriteLine();
150-
foreach (var mySqlInstance in mySqlInstances)
143+
try
151144
{
152-
if (mySqlInstance.PrimaryEndpoint.IsAllocated)
145+
var aspireStore = e.Services.GetRequiredService<IAspireStore>();
146+
147+
// Deterministic file path for the configuration file based on its content
148+
var configStoreFilename = aspireStore.GetFileNameWithContent($"{builder.Resource.Name}-config.user.inc.php", tempConfigFile);
149+
150+
// Need to grant read access to the config file on unix like systems.
151+
if (!OperatingSystem.IsWindows())
152+
{
153+
File.SetUnixFileMode(configStoreFilename, FileMode644);
154+
}
155+
156+
phpMyAdminContainerBuilder.WithBindMount(configStoreFilename, "/etc/phpmyadmin/config.user.inc.php");
157+
}
158+
finally
159+
{
160+
try
161+
{
162+
File.Delete(tempConfigFile);
163+
}
164+
catch
153165
{
154-
var endpoint = mySqlInstance.PrimaryEndpoint;
155-
writer.WriteLine("$i++;");
156-
// PhpMyAdmin assumes MySql is being accessed over a default Aspire container network and hardcodes the resource address
157-
// This will need to be refactored once updated service discovery APIs are available
158-
writer.WriteLine($"$cfg['Servers'][$i]['host'] = '{endpoint.Resource.Name}:{endpoint.TargetPort}';");
159-
writer.WriteLine($"$cfg['Servers'][$i]['verbose'] = '{mySqlInstance.Name}';");
160-
writer.WriteLine($"$cfg['Servers'][$i]['auth_type'] = 'cookie';");
161-
writer.WriteLine($"$cfg['Servers'][$i]['user'] = 'root';");
162-
writer.WriteLine($"$cfg['Servers'][$i]['password'] = '{mySqlInstance.PasswordParameter.Value}';");
163-
writer.WriteLine($"$cfg['Servers'][$i]['AllowNoPassword'] = true;");
164-
writer.WriteLine();
165166
}
166167
}
167-
writer.WriteLine("$cfg['DefaultServer'] = 1;");
168-
writer.WriteLine("?>");
169168
}
170169

171170
return Task.CompletedTask;
@@ -235,4 +234,38 @@ public static IResourceBuilder<MySqlServerResource> WithInitBindMount(this IReso
235234

236235
return builder.WithBindMount(source, "/docker-entrypoint-initdb.d", isReadOnly);
237236
}
237+
238+
private static string WritePhpMyAdminConfiguration(IEnumerable<MySqlServerResource> mySqlInstances)
239+
{
240+
// This temporary file is not used by the container, it will be copied and then deleted
241+
var filePath = Path.GetTempFileName();
242+
243+
using var writer = new StreamWriter(filePath);
244+
245+
writer.WriteLine("<?php");
246+
writer.WriteLine();
247+
writer.WriteLine("$i = 0;");
248+
writer.WriteLine();
249+
foreach (var mySqlInstance in mySqlInstances)
250+
{
251+
if (mySqlInstance.PrimaryEndpoint.IsAllocated)
252+
{
253+
var endpoint = mySqlInstance.PrimaryEndpoint;
254+
writer.WriteLine("$i++;");
255+
// PhpMyAdmin assumes MySql is being accessed over a default Aspire container network and hardcodes the resource address
256+
// This will need to be refactored once updated service discovery APIs are available
257+
writer.WriteLine($"$cfg['Servers'][$i]['host'] = '{endpoint.Resource.Name}:{endpoint.TargetPort}';");
258+
writer.WriteLine($"$cfg['Servers'][$i]['verbose'] = '{mySqlInstance.Name}';");
259+
writer.WriteLine($"$cfg['Servers'][$i]['auth_type'] = 'cookie';");
260+
writer.WriteLine($"$cfg['Servers'][$i]['user'] = 'root';");
261+
writer.WriteLine($"$cfg['Servers'][$i]['password'] = '{mySqlInstance.PasswordParameter.Value}';");
262+
writer.WriteLine($"$cfg['Servers'][$i]['AllowNoPassword'] = true;");
263+
writer.WriteLine();
264+
}
265+
}
266+
writer.WriteLine("$cfg['DefaultServer'] = 1;");
267+
writer.WriteLine("?>");
268+
269+
return filePath;
270+
}
238271
}

0 commit comments

Comments
 (0)