public void InstallWorkloadManifest(ManifestId manifestId, ManifestVersion manifestVersion, SdkFeatureBand sdkFeatureBand) { string packagePath = null; string tempExtractionDir = null; string tempBackupDir = null; var manifestPath = Path.Combine(_dotnetDir, "sdk-manifests", sdkFeatureBand.ToString(), manifestId.ToString()); _reporter.WriteLine(string.Format(LocalizableStrings.InstallingWorkloadManifest, manifestId, manifestVersion)); try { TransactionalAction.Run( action: () => { packagePath = _nugetPackageDownloader.DownloadPackageAsync(WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId), new NuGetVersion(manifestVersion.ToString())).Result; tempExtractionDir = Path.Combine(_tempPackagesDir.Value, $"{manifestId}-{manifestVersion}-extracted"); Directory.CreateDirectory(tempExtractionDir); var manifestFiles = _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempExtractionDir)).Result; if (Directory.Exists(manifestPath) && Directory.GetFileSystemEntries(manifestPath).Any()) { // Backup existing manifest data for roll back purposes tempBackupDir = Path.Combine(_tempPackagesDir.Value, $"{manifestId}-{manifestVersion}-backup"); if (Directory.Exists(tempBackupDir)) { Directory.Delete(tempBackupDir, true); } FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(manifestPath, tempBackupDir)); } Directory.CreateDirectory(Path.GetDirectoryName(manifestPath)); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(Path.Combine(tempExtractionDir, "data"), manifestPath)); }, rollback: () => { if (!string.IsNullOrEmpty(tempBackupDir) && Directory.Exists(tempBackupDir)) { FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(tempBackupDir, manifestPath)); } }); // Delete leftover dirs and files if (!string.IsNullOrEmpty(packagePath) && File.Exists(packagePath)) { File.Delete(packagePath); } var versionDir = Path.GetDirectoryName(packagePath); if (Directory.Exists(versionDir) && !Directory.GetFileSystemEntries(versionDir).Any()) { Directory.Delete(versionDir); var idDir = Path.GetDirectoryName(versionDir); if (Directory.Exists(idDir) && !Directory.GetFileSystemEntries(idDir).Any()) { Directory.Delete(idDir); } } if (!string.IsNullOrEmpty(tempExtractionDir) && Directory.Exists(tempExtractionDir)) { Directory.Delete(tempExtractionDir, true); } if (!string.IsNullOrEmpty(tempBackupDir) && Directory.Exists(tempBackupDir)) { Directory.Delete(tempBackupDir, true); } } catch (Exception e) { throw new Exception(string.Format(LocalizableStrings.FailedToInstallWorkloadManifest, manifestId, manifestVersion, e.Message)); } }
public IToolPackage InstallPackage( string packageId, string packageVersion = null, string targetFramework = null, FilePath?nugetConfig = null, string source = null, string verbosity = null) { if (packageId == null) { throw new ArgumentNullException(nameof(packageId)); } var packageRootDirectory = _store.Root.WithSubDirectories(packageId); string rollbackDirectory = null; return(TransactionalAction.Run <IToolPackage>( action: () => { try { var stageDirectory = _store.Root.WithSubDirectories(StagingDirectory, Path.GetRandomFileName()); Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; var tempProject = CreateTempProject( packageId: packageId, packageVersion: packageVersion, targetFramework: targetFramework ?? BundledTargetFramework.GetTargetFrameworkMoniker(), restoreDirectory: stageDirectory); try { _projectRestorer.Restore( tempProject, stageDirectory, nugetConfig, source, verbosity); } finally { File.Delete(tempProject.Value); } packageVersion = Path.GetFileName( Directory.EnumerateDirectories( stageDirectory.WithSubDirectories(packageId).Value).Single()); var packageDirectory = packageRootDirectory.WithSubDirectories(packageVersion); if (Directory.Exists(packageDirectory.Value)) { throw new ToolPackageException( string.Format( CommonLocalizableStrings.ToolPackageConflictPackageId, packageId, packageVersion)); } Directory.CreateDirectory(packageRootDirectory.Value); Directory.Move(stageDirectory.Value, packageDirectory.Value); rollbackDirectory = packageDirectory.Value; return new ToolPackageInstance( _store, packageId, packageVersion, packageDirectory); } catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException) { throw new ToolPackageException( string.Format( CommonLocalizableStrings.FailedToInstallToolPackage, packageId, ex.Message), ex); } }, rollback: () => { if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory)) { Directory.Delete(rollbackDirectory, true); } // Delete the root if it is empty if (Directory.Exists(packageRootDirectory.Value) && !Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any()) { Directory.Delete(packageRootDirectory.Value, false); } })); }
public IToolPackage InstallPackage(PackageId packageId, VersionRange versionRange = null, string targetFramework = null, FilePath?nugetConfig = null, DirectoryPath?rootConfigDirectory = null, string[] additionalFeeds = null, string verbosity = null) { var packageRootDirectory = _store.GetRootPackageDirectory(packageId); string rollbackDirectory = null; return(TransactionalAction.Run <IToolPackage>( action: () => { try { var stageDirectory = _store.GetRandomStagingDirectory(); Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; var tempProject = CreateTempProject( packageId: packageId, versionRange: versionRange, targetFramework: targetFramework ?? BundledTargetFramework.GetTargetFrameworkMoniker(), restoreDirectory: stageDirectory, assetJsonOutputDirectory: stageDirectory, rootConfigDirectory: rootConfigDirectory, additionalFeeds: additionalFeeds); try { _projectRestorer.Restore( tempProject, nugetConfig, verbosity: verbosity); } finally { File.Delete(tempProject.Value); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); var packageDirectory = _store.GetPackageDirectory(packageId, version); if (Directory.Exists(packageDirectory.Value)) { throw new ToolPackageException( string.Format( CommonLocalizableStrings.ToolPackageConflictPackageId, packageId, version.ToNormalizedString())); } Directory.CreateDirectory(packageRootDirectory.Value); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(stageDirectory.Value, packageDirectory.Value)); rollbackDirectory = packageDirectory.Value; return new ToolPackageInstance(_store, packageId, version, packageDirectory); } catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException) { throw new ToolPackageException( string.Format( CommonLocalizableStrings.FailedToInstallToolPackage, packageId, ex.Message), ex); } }, rollback: () => { if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory)) { Directory.Delete(rollbackDirectory, true); } // Delete the root if it is empty if (Directory.Exists(packageRootDirectory.Value) && !Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any()) { Directory.Delete(packageRootDirectory.Value, false); } })); }
public IToolPackage InstallPackage(PackageId packageId, VersionRange versionRange = null, string targetFramework = null, FilePath?nugetConfig = null, DirectoryPath?rootConfigDirectory = null, string[] additionalFeeds = null, string verbosity = null) { var packageRootDirectory = _store.GetRootPackageDirectory(packageId); string rollbackDirectory = null; return(TransactionalAction.Run <IToolPackage>( action: () => { var stageDirectory = _store.GetRandomStagingDirectory(); _fileSystem.Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; var tempProject = new FilePath(Path.Combine(stageDirectory.Value, ProjectFileName)); // Write a fake project with the requested package id, version, and framework _fileSystem.File.WriteAllText( tempProject.Value, $"{packageId}:{versionRange?.ToString("S", new VersionRangeFormatter()) ?? "*"}:{targetFramework}"); // Perform a restore on the fake project _projectRestorer.Restore( tempProject, stageDirectory, nugetConfig, verbosity); if (_installCallback != null) { _installCallback(); } var version = _store.GetStagedPackageVersion(stageDirectory, packageId); var packageDirectory = _store.GetPackageDirectory(packageId, version); if (_fileSystem.Directory.Exists(packageDirectory.Value)) { throw new ToolPackageException( string.Format( CommonLocalizableStrings.ToolPackageConflictPackageId, packageId, version.ToNormalizedString())); } _fileSystem.Directory.CreateDirectory(packageRootDirectory.Value); _fileSystem.Directory.Move(stageDirectory.Value, packageDirectory.Value); rollbackDirectory = packageDirectory.Value; IEnumerable <string> warnings = null; _warningsMap.TryGetValue(packageId, out warnings); IReadOnlyList <FilePath> packedShims = null; _packagedShimsMap.TryGetValue(packageId, out packedShims); return new ToolPackageMock(_fileSystem, packageId, version, packageDirectory, warnings: warnings, packagedShims: packedShims); }, rollback: () => { if (rollbackDirectory != null && _fileSystem.Directory.Exists(rollbackDirectory)) { _fileSystem.Directory.Delete(rollbackDirectory, true); } if (_fileSystem.Directory.Exists(packageRootDirectory.Value) && !_fileSystem.Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any()) { _fileSystem.Directory.Delete(packageRootDirectory.Value, false); } })); }
public void InstallWorkloadPack(PackInfo packInfo, SdkFeatureBand sdkFeatureBand, DirectoryPath?offlineCache = null) { _reporter.WriteLine(string.Format(LocalizableStrings.InstallingPackVersionMessage, packInfo.Id, packInfo.Version)); var tempDirsToDelete = new List <string>(); var tempFilesToDelete = new List <string>(); try { TransactionalAction.Run( action: () => { if (!PackIsInstalled(packInfo)) { string packagePath; if (offlineCache == null || !offlineCache.HasValue) { packagePath = _nugetPackageDownloader.DownloadPackageAsync(new PackageId(packInfo.ResolvedPackageId), new NuGetVersion(packInfo.Version), _packageSourceLocation).Result; tempFilesToDelete.Add(packagePath); } else { _reporter.WriteLine(string.Format(LocalizableStrings.UsingCacheForPackInstall, packInfo.Id, packInfo.Version, offlineCache)); packagePath = Path.Combine(offlineCache.Value.Value, $"{packInfo.ResolvedPackageId}.{packInfo.Version}.nupkg"); if (!File.Exists(packagePath)) { throw new Exception(string.Format(LocalizableStrings.CacheMissingPackage, packInfo.ResolvedPackageId, packInfo.Version, offlineCache)); } } if (!Directory.Exists(Path.GetDirectoryName(packInfo.Path))) { Directory.CreateDirectory(Path.GetDirectoryName(packInfo.Path)); } if (IsSingleFilePack(packInfo)) { File.Copy(packagePath, packInfo.Path); } else { var tempExtractionDir = Path.Combine(_tempPackagesDir.Value, $"{packInfo.Id}-{packInfo.Version}-extracted"); tempDirsToDelete.Add(tempExtractionDir); Directory.CreateDirectory(tempExtractionDir); var packFiles = _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempExtractionDir)).Result; FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(tempExtractionDir, packInfo.Path)); } } else { _reporter.WriteLine(string.Format(LocalizableStrings.WorkloadPackAlreadyInstalledMessage, packInfo.Id, packInfo.Version)); } WritePackInstallationRecord(packInfo, sdkFeatureBand); }, rollback: () => { try { _reporter.WriteLine(string.Format(LocalizableStrings.RollingBackPackInstall, packInfo.Id)); RollBackWorkloadPackInstall(packInfo, sdkFeatureBand); } catch (Exception e) { // Don't hide the original error if roll back fails _reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, e.Message)); } }); } finally { // Delete leftover dirs and files foreach (var file in tempFilesToDelete) { if (File.Exists(file)) { File.Delete(file); } } foreach (var dir in tempDirsToDelete) { if (Directory.Exists(dir)) { Directory.Delete(dir, true); } } } }