Skip to content

Commit

Permalink
Merge pull request #28477 from nagilson/nagilson-internal-tempfix-GA
Browse files Browse the repository at this point in the history
[GA / 7.0.1xx Internal -> External Port] Fix SDK Temp Paths
  • Loading branch information
marcpopMSFT authored Oct 12, 2022
2 parents ac62cb1 + fb16944 commit d639dd5
Show file tree
Hide file tree
Showing 24 changed files with 162 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ internal MsBuildFileSetFactory(

public async Task<FileSet> CreateAsync(CancellationToken cancellationToken)
{
var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
var watchList = Path.GetTempFileName();
try
{
var projectDir = Path.GetDirectoryName(_projectFile);
Expand Down
1 change: 1 addition & 0 deletions src/BuiltInTools/dotnet-watch/dotnet-watch.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<PackageReference Include="Microsoft.Build.Locator" Version="$(MicrosoftBuildLocatorPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="$(MicrosoftCodeAnalysisCSharpFeaturesPackageVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="$(MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion)" />
<Compile Include="$(RepoRoot)src\Common\PathUtilities.cs" LinkBase="Common" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Microsoft.Extensions.EnvironmentAbstractions
{
internal class DirectoryWrapper: IDirectory
internal class DirectoryWrapper : IDirectory
{
public bool Exists(string path)
{
Expand All @@ -19,6 +19,11 @@ public ITemporaryDirectory CreateTemporaryDirectory()
return new TemporaryDirectory();
}

public string CreateTemporarySubdirectory()
{
return CreateTemporaryDirectory().DirectoryPath;
}

public IEnumerable<string> EnumerateDirectories(string path)
{
return Directory.EnumerateDirectories(path);
Expand Down
2 changes: 1 addition & 1 deletion src/Cli/Microsoft.DotNet.InternalAbstractions/FilePath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public string ToQuotedString()

public override string ToString()
{
return ToQuotedString();
return Value;
}

public DirectoryPath GetDirectoryPath()
Expand Down
4 changes: 4 additions & 0 deletions src/Cli/Microsoft.DotNet.InternalAbstractions/IDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,9 @@ internal interface IDirectory
void Delete(string path, bool recursive);

void Move(string source, string destination);


/// <Summary>Returns a new directory created under the temp folder. Can be on the mock under test or the real temp file folder.</Summary>
string CreateTemporarySubdirectory();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
<IsPackable>true</IsPackable>
</PropertyGroup>

<ItemGroup>
<Compile Include="$(RepoRoot)src\Common\PathUtilities.cs" LinkBase="Common" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Extensions.EnvironmentAbstractions;
using System.IO;
using Microsoft.Extensions.EnvironmentAbstractions;
using Microsoft.DotNet;

namespace Microsoft.DotNet.InternalAbstractions
{
Expand All @@ -12,8 +13,7 @@ internal class TemporaryDirectory : ITemporaryDirectory

public TemporaryDirectory()
{
DirectoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Directory.CreateDirectory(DirectoryPath);
DirectoryPath = Path.Combine(PathUtilities.CreateTempSubdirectory());
}

public void Dispose()
Expand Down
14 changes: 9 additions & 5 deletions src/Cli/dotnet/ShellShim/ShellShimRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ public void CreateShim(FilePath targetExecutablePath, ToolCommandName commandNam
ex);
}
},
rollback: () => {
rollback: () =>
{
foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value)))
{
File.Delete(file.Value);
Expand All @@ -97,12 +98,13 @@ public void RemoveShim(ToolCommandName commandName)
{
var files = new Dictionary<string, string>();
TransactionalAction.Run(
action: () => {
action: () =>
{
try
{
foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value)))
{
var tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
var tempPath = Path.Combine(_fileSystem.Directory.CreateTemporarySubdirectory(), Path.GetRandomFileName());
FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath));
files[file.Value] = tempPath;
}
Expand All @@ -118,13 +120,15 @@ public void RemoveShim(ToolCommandName commandName)
ex);
}
},
commit: () => {
commit: () =>
{
foreach (var value in files.Values)
{
_fileSystem.File.Delete(value);
}
},
rollback: () => {
rollback: () =>
{
foreach (var kvp in files)
{
FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(kvp.Value, kvp.Key));
Expand Down
47 changes: 2 additions & 45 deletions src/Cli/dotnet/SudoEnvironmentDirectoryOverride.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@

using System;
using System.CommandLine;
using System.CommandLine.Parsing;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Common;
using NuGet.Common;
using NuGet.Configuration;

Expand All @@ -18,8 +16,6 @@ namespace Microsoft.DotNet.Cli
/// </summary>
public static class SudoEnvironmentDirectoryOverride
{
private const string SudoHomeDirectory = "/tmp/dotnet_sudo_home/";

/// <summary>
/// Not for security use. Detect if command is running under sudo
/// via if SUDO_UID being set.
Expand All @@ -38,22 +34,9 @@ public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult)
{
if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult))
{
if (!TempHomeIsOnlyRootWritable(SudoHomeDirectory))
{
try
{
Directory.Delete(SudoHomeDirectory, recursive: true);
}
catch (DirectoryNotFoundException)
{
// Avoid read after write race condition
}
}

Directory.CreateDirectory(SudoHomeDirectory);

string sudoHome = PathUtilities.CreateTempSubdirectory();
var homeBeforeOverride = Path.Combine(Environment.GetEnvironmentVariable("HOME"));
Environment.SetEnvironmentVariable("HOME", SudoHomeDirectory);
Environment.SetEnvironmentVariable("HOME", sudoHome);

CopyUserNuGetConfigToOverriddenHome(homeBeforeOverride);
}
Expand Down Expand Up @@ -107,31 +90,5 @@ private static void CopyUserNuGetConfigToOverriddenHome(string homeBeforeOverrid

private static bool IsRunningWorkloadCommand(ParseResult parseResult) =>
parseResult.RootSubCommandResult() == (WorkloadCommandParser.GetCommand().Name);

private static bool TempHomeIsOnlyRootWritable(string path)
{
if (StatInterop.LStat(path, out StatInterop.FileStatus fileStat) != 0)
{
return false;
}

return IsOwnedByRoot(fileStat) && GroupCannotWrite(fileStat) &&
OtherUserCannotWrite(fileStat);
}

private static bool OtherUserCannotWrite(StatInterop.FileStatus fileStat)
{
return (fileStat.Mode & (int) StatInterop.Permissions.S_IWOTH) == 0;
}

private static bool GroupCannotWrite(StatInterop.FileStatus fileStat)
{
return (fileStat.Mode & (int) StatInterop.Permissions.S_IWGRP) == 0;
}

private static bool IsOwnedByRoot(StatInterop.FileStatus fileStat)
{
return fileStat.Uid == 0;
}
}
}
48 changes: 22 additions & 26 deletions src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using Microsoft.DotNet.Configurer;
using Microsoft.DotNet.Tools;
using Microsoft.Extensions.EnvironmentAbstractions;
using NuGet.ProjectModel;
using NuGet.Versioning;

namespace Microsoft.DotNet.ToolPackage
Expand Down Expand Up @@ -46,17 +45,18 @@ public IToolPackage InstallPackage(
string rollbackDirectory = null;

return TransactionalAction.Run<IToolPackage>(
action: () => {
action: () =>
{
try
{
var stageDirectory = _store.GetRandomStagingDirectory();
Directory.CreateDirectory(stageDirectory.Value);
rollbackDirectory = stageDirectory.Value;

var tempProject = CreateTempProject(
string tempProject = CreateDirectoryWithTempProject(
packageId: packageId,
versionRange: versionRange,
targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework,
targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework,
restoreDirectory: stageDirectory,
assetJsonOutputDirectory: stageDirectory,
rootConfigDirectory: packageLocation.RootConfigDirectory,
Expand All @@ -65,13 +65,13 @@ public IToolPackage InstallPackage(
try
{
_projectRestorer.Restore(
tempProject,
new FilePath(tempProject),
packageLocation,
verbosity: verbosity);
}
finally
{
File.Delete(tempProject.Value);
File.Delete(tempProject);
}

var version = _store.GetStagedPackageVersion(stageDirectory, packageId);
Expand Down Expand Up @@ -104,7 +104,8 @@ public IToolPackage InstallPackage(
ex);
}
},
rollback: () => {
rollback: () =>
{
if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory))
{
Directory.Delete(rollbackDirectory, true);
Expand All @@ -126,36 +127,33 @@ public IToolPackage InstallPackageToExternalManagedLocation(
string targetFramework = null,
string verbosity = null)
{
var tempDirectoryForAssetJson = new DirectoryPath(Path.GetTempPath())
.WithSubDirectories(Path.GetRandomFileName());

Directory.CreateDirectory(tempDirectoryForAssetJson.Value);
var tempDirectoryForAssetJson = PathUtilities.CreateTempSubdirectory();

var tempProject = CreateTempProject(
string tempProject = CreateDirectoryWithTempProject(
packageId: packageId,
versionRange: versionRange,
targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework,
assetJsonOutputDirectory: tempDirectoryForAssetJson,
assetJsonOutputDirectory: new DirectoryPath(tempDirectoryForAssetJson),
restoreDirectory: null,
rootConfigDirectory: packageLocation.RootConfigDirectory,
additionalFeeds: packageLocation.AdditionalFeeds);

try
{
_projectRestorer.Restore(
tempProject,
new FilePath(tempProject),
packageLocation,
verbosity: verbosity);
}
finally
{
File.Delete(tempProject.Value);
File.Delete(tempProject);
}

return ToolPackageInstance.CreateFromAssetFile(packageId, tempDirectoryForAssetJson);
return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson));
}

private FilePath CreateTempProject(
private string CreateDirectoryWithTempProject(
PackageId packageId,
VersionRange versionRange,
string targetFramework,
Expand All @@ -164,16 +162,14 @@ private FilePath CreateTempProject(
DirectoryPath? rootConfigDirectory,
string[] additionalFeeds)
{
var tempProject = _tempProject ?? new DirectoryPath(Path.GetTempPath())
.WithSubDirectories(Path.GetRandomFileName())
.WithFile("restore.csproj");

if (Path.GetExtension(tempProject.Value) != "csproj")
string tempProject;
if (_tempProject != null && _tempProject.HasValue)
{
tempProject = new FilePath(Path.ChangeExtension(tempProject.Value, "csproj"));
tempProject = _tempProject.Value.Value;
Directory.CreateDirectory(Path.GetDirectoryName(tempProject));
}

Directory.CreateDirectory(tempProject.GetDirectoryPath().Value);
else
tempProject = Path.Combine(PathUtilities.CreateTempSubdirectory(), "restore.csproj");

var tempProjectContent = new XDocument(
new XElement("Project",
Expand Down Expand Up @@ -203,7 +199,7 @@ private FilePath CreateTempProject(
new XAttribute("Project", "Sdk.targets"),
new XAttribute("Sdk", "Microsoft.NET.Sdk"))));

File.WriteAllText(tempProject.Value, tempProjectContent.ToString());
File.WriteAllText(tempProject, tempProjectContent.ToString());
return tempProject;
}

Expand Down
5 changes: 1 addition & 4 deletions src/Cli/dotnet/commands/InstallingWorkloadCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Parsing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Deployment.DotNet.Releases;
using Microsoft.DotNet.Cli;
Expand All @@ -17,7 +15,6 @@
using Microsoft.DotNet.Configurer;
using Microsoft.DotNet.ToolPackage;
using Microsoft.DotNet.Workloads.Workload.Install;
using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord;
using Microsoft.Extensions.EnvironmentAbstractions;
using Microsoft.NET.Sdk.WorkloadManifestReader;
using NuGet.Versioning;
Expand Down Expand Up @@ -79,7 +76,7 @@ public InstallingWorkloadCommand(
var sourceOption = parseResult.GetValueForOption(InstallingWorkloadCommandParser.SourceOption);
_packageSourceLocation = string.IsNullOrEmpty(configOption) && (sourceOption == null || !sourceOption.Any()) ? null :
new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), sourceFeedOverrides: sourceOption);

var sdkWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _installedSdkVersion.ToString(), userProfileDir);
_workloadResolver = workloadResolver ?? WorkloadResolver.Create(sdkWorkloadManifestProvider, _dotnetPath, _installedSdkVersion.ToString(), _userProfileDir);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Parsing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
Expand Down Expand Up @@ -72,7 +71,7 @@ public ToolInstallGlobalOrToolPathCommand(
_environmentPathInstruction = environmentPathInstruction
?? EnvironmentPathFactory.CreateEnvironmentPathInstruction();
_createShellShimRepository = createShellShimRepository ?? ShellShimRepositoryFactory.CreateShellShimRepository;
var tempDir = new DirectoryPath(Path.Combine(Path.GetTempPath(), "dotnet-tool-install"));
var tempDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory());
var configOption = parseResult.GetValueForOption(ToolInstallCommandParser.ConfigOption);
var sourceOption = parseResult.GetValueForOption(ToolInstallCommandParser.AddSourceOption);
var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption);
Expand Down Expand Up @@ -143,7 +142,7 @@ public override int Execute()
}
else
{
framework = string.IsNullOrEmpty(_framework) ?
framework = string.IsNullOrEmpty(_framework) ?
null :
NuGetFramework.Parse(_framework);
}
Expand Down
Loading

0 comments on commit d639dd5

Please sign in to comment.