Example #1
0
 /// <summary>
 /// Moves a file from one location to another if the destination file does not already exist.
 /// </summary>
 /// <param name="sourceFile">The source file to move.</param>
 /// <param name="destinationFile">The destination where the source file will be moved.</param>
 protected void MoveFile(string sourceFile, string destinationFile)
 {
     if (!File.Exists(destinationFile))
     {
         FileAccessRetrier.RetryOnMoveAccessFailure(() => File.Move(sourceFile, destinationFile));
         Log?.LogMessage($"Moved '{sourceFile}' to '{destinationFile}'");
     }
 }
Example #2
0
        private async Task UpdateAdvertisingManifestAsync(ManifestId manifestId, bool includePreviews)
        {
            string packagePath    = null;
            string extractionPath = null;

            try
            {
                var adManifestPath = GetAdvertisingManifestPath(_sdkFeatureBand, manifestId);
                try
                {
                    packagePath = await _nugetPackageDownloader.DownloadPackageAsync(GetManifestPackageId(_sdkFeatureBand, manifestId), includePreview : includePreviews);
                }
                catch (NuGetPackageNotFoundException)
                {
                    _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestPackageDoesNotExist, manifestId));
                }
                extractionPath = Path.Combine(_userHome, ".dotnet", "sdk-advertising-temp", $"{manifestId}-extracted");
                Directory.CreateDirectory(extractionPath);
                var resultingFiles = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(extractionPath));

                if (Directory.Exists(adManifestPath))
                {
                    Directory.Delete(adManifestPath, true);
                }
                Directory.CreateDirectory(Path.GetDirectoryName(adManifestPath));
                FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(Path.Combine(extractionPath, "data"), adManifestPath));

                _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestUpdated, manifestId));
            }
            catch (Exception e)
            {
                _reporter.WriteLine(string.Format(LocalizableStrings.FailedAdManifestUpdate, manifestId, e.Message));
            }
            finally
            {
                if (!string.IsNullOrEmpty(extractionPath) && Directory.Exists(extractionPath))
                {
                    Directory.Delete(extractionPath, true);
                }

                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);
                    }
                }
            }
        }
Example #3
0
        public void Uninstall()
        {
            var    rootDirectory        = PackageDirectory.GetParentPath();
            string tempPackageDirectory = null;

            TransactionalAction.Run(
                action: () =>
            {
                try
                {
                    if (Directory.Exists(PackageDirectory.Value))
                    {
                        // Use the staging directory for uninstall
                        // This prevents cross-device moves when temp is mounted to a different device
                        var tempPath = _store.GetRandomStagingDirectory().Value;
                        FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(PackageDirectory.Value, tempPath));
                        tempPackageDirectory = tempPath;
                    }

                    if (Directory.Exists(rootDirectory.Value) &&
                        !Directory.EnumerateFileSystemEntries(rootDirectory.Value).Any())
                    {
                        Directory.Delete(rootDirectory.Value, false);
                    }
                }
                catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException)
                {
                    throw new ToolPackageException(
                        string.Format(
                            CommonLocalizableStrings.FailedToUninstallToolPackage,
                            Id,
                            ex.Message),
                        ex);
                }
            },
                commit: () =>
            {
                if (tempPackageDirectory != null)
                {
                    Directory.Delete(tempPackageDirectory, true);
                }
            },
                rollback: () =>
            {
                if (tempPackageDirectory != null)
                {
                    Directory.CreateDirectory(rootDirectory.Value);
                    FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(tempPackageDirectory, PackageDirectory.Value));
                }
            });
        }
Example #4
0
        public static void CreateIfNotExists(this IFileSystem fileSystem, string filePath)
        {
            // retry if there is 2 CLI process trying to create file (for example sentinel file)
            // at the same time
            FileAccessRetrier.RetryOnIOException(() =>
            {
                var parentDirectory = Path.GetDirectoryName(filePath);
                if (!fileSystem.File.Exists(filePath))
                {
                    if (!fileSystem.Directory.Exists(parentDirectory))
                    {
                        fileSystem.Directory.CreateDirectory(parentDirectory);
                    }

                    fileSystem.File.CreateEmptyFile(filePath);
                }
            });
        }
        /// <summary>
        /// To make NuGet honor the user's NuGet config file.
        /// Copying instead of using the file directoy to avoid existing file being set higher permission
        /// Try to delete the existing NuGet config file in "/tmp/dotnet_sudo_home/"
        /// to avoid different user's NuGet config getting mixed.
        /// </summary>
        private static void CopyUserNuGetConfigToOverriddenHome(string homeBeforeOverride)
        {
            // https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Common/PathUtil/NuGetEnvironment.cs#L139
            // home is cache in NuGet we cannot directly use the call
            var userSettingsDir = Path.Combine(homeBeforeOverride, ".nuget", "NuGet");

            string userNuGetConfig = Settings.OrderedSettingsFileNames
                                     .Select(fileName => Path.Combine(userSettingsDir, fileName))
                                     .FirstOrDefault(f => File.Exists(f));

            var overridenSettingsDir = NuGetEnvironment.GetFolderPath(NuGetFolderPath.UserSettingsDirectory);
            var overridenNugetConfig = Path.Combine(overridenSettingsDir, Settings.DefaultSettingsFileName);

            if (File.Exists(overridenNugetConfig))
            {
                try
                {
                    FileAccessRetrier.RetryOnIOException(
                        () => File.Delete(overridenNugetConfig));
                }
                catch
                {
                    // best effort to remove
                }
            }

            if (userNuGetConfig != default)
            {
                try
                {
                    FileAccessRetrier.RetryOnIOException(
                        () => File.Copy(userNuGetConfig, overridenNugetConfig, overwrite: true));
                }
                catch
                {
                    // best effort to copy
                }
            }
        }
Example #6
0
        public void RemoveShim(ToolCommandName commandName)
        {
            var files = new Dictionary <string, string>();

            TransactionalAction.Run(
                action: () => {
                try
                {
                    foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value)))
                    {
                        var tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                        FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath));
                        files[file.Value] = tempPath;
                    }
                }
                catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException)
                {
                    throw new ShellShimException(
                        string.Format(
                            CommonLocalizableStrings.FailedToRemoveShellShim,
                            commandName.ToString(),
                            ex.Message
                            ),
                        ex);
                }
            },
                commit: () => {
                foreach (var value in files.Values)
                {
                    _fileSystem.File.Delete(value);
                }
            },
                rollback: () => {
                foreach (var kvp in files)
                {
                    FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(kvp.Value, kvp.Key));
                }
            });
        }
Example #7
0
        public IToolPackage InstallPackage(
            PackageLocation packageLocation,
            PackageId packageId,
            VersionRange versionRange = null,
            string targetFramework    = 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: packageLocation.RootConfigDirectory,
                        additionalFeeds: packageLocation.AdditionalFeeds);

                    try
                    {
                        _projectRestorer.Restore(
                            tempProject,
                            packageLocation,
                            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(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 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).GetAwaiter().GetResult();
                            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)).GetAwaiter().GetResult();

                            FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(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, offlineCache);
                    }
                    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);
                    }
                }
            }
        }
        public void InstallWorkloadManifest(ManifestId manifestId, ManifestVersion manifestVersion, SdkFeatureBand sdkFeatureBand, DirectoryPath?offlineCache = null, bool isRollback = false)
        {
            string packagePath       = null;
            string tempExtractionDir = null;
            string tempBackupDir     = null;
            string rootInstallDir    = WorkloadFileBasedInstall.IsUserLocal(_dotnetDir, sdkFeatureBand.ToString()) ? _userProfileDir : _dotnetDir;
            var    manifestPath      = Path.Combine(rootInstallDir, "sdk-manifests", sdkFeatureBand.ToString(), manifestId.ToString());

            _reporter.WriteLine(string.Format(LocalizableStrings.InstallingWorkloadManifest, manifestId, manifestVersion));

            try
            {
                TransactionalAction.Run(
                    action: () =>
                {
                    if (offlineCache == null || !offlineCache.HasValue)
                    {
                        packagePath = _nugetPackageDownloader.DownloadPackageAsync(WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId),
                                                                                   new NuGetVersion(manifestVersion.ToString()), _packageSourceLocation).GetAwaiter().GetResult();
                    }
                    else
                    {
                        packagePath = Path.Combine(offlineCache.Value.Value, $"{WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId)}.{manifestVersion}.nupkg");
                        if (!File.Exists(packagePath))
                        {
                            throw new Exception(string.Format(LocalizableStrings.CacheMissingPackage, WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId), manifestVersion, offlineCache));
                        }
                    }
                    tempExtractionDir = Path.Combine(_tempPackagesDir.Value, $"{manifestId}-{manifestVersion}-extracted");
                    Directory.CreateDirectory(tempExtractionDir);
                    var manifestFiles = _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempExtractionDir)).GetAwaiter().GetResult();

                    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(() => DirectoryPath.MoveDirectory(manifestPath, tempBackupDir));
                    }
                    Directory.CreateDirectory(Path.GetDirectoryName(manifestPath));
                    FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(Path.Combine(tempExtractionDir, "data"), manifestPath));
                },
                    rollback: () =>
                {
                    if (!string.IsNullOrEmpty(tempBackupDir) && Directory.Exists(tempBackupDir))
                    {
                        FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(tempBackupDir, manifestPath));
                    }
                });

                // Delete leftover dirs and files
                if (!string.IsNullOrEmpty(packagePath) && File.Exists(packagePath) && (offlineCache == null || !offlineCache.HasValue))
                {
                    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));
            }
        }
Example #10
0
        private async Task UpdateAdvertisingManifestAsync(ManifestId manifestId, bool includePreviews, DirectoryPath?offlineCache = null)
        {
            string packagePath    = null;
            string extractionPath = null;

            try
            {
                var adManifestPath = GetAdvertisingManifestPath(_sdkFeatureBand, manifestId);
                if (offlineCache == null || !offlineCache.HasValue)
                {
                    try
                    {
                        packagePath = await _nugetPackageDownloader.DownloadPackageAsync(
                            GetManifestPackageId(_sdkFeatureBand, manifestId),
                            packageSourceLocation : _packageSourceLocation,
                            includePreview : includePreviews);
                    }
                    catch (NuGetPackageNotFoundException)
                    {
                        _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestPackageDoesNotExist, manifestId));
                    }
                }
                else
                {
                    packagePath = Directory.GetFiles(offlineCache.Value.Value)
                                  .Where(path => path.EndsWith(".nupkg"))
                                  .Where(path => Path.GetFileName(path).StartsWith(GetManifestPackageId(_sdkFeatureBand, manifestId).ToString()))
                                  .Max();
                    if (!File.Exists(packagePath))
                    {
                        throw new Exception(string.Format(LocalizableStrings.CacheMissingPackage, GetManifestPackageId(_sdkFeatureBand, manifestId), "*", offlineCache));
                    }
                }

                extractionPath = Path.Combine(_tempDirPath, "dotnet-sdk-advertising-temp", $"{manifestId}-extracted");
                Directory.CreateDirectory(extractionPath);
                var resultingFiles = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(extractionPath));

                if (Directory.Exists(adManifestPath))
                {
                    Directory.Delete(adManifestPath, true);
                }
                Directory.CreateDirectory(Path.GetDirectoryName(adManifestPath));
                FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(Path.Combine(extractionPath, "data"), adManifestPath));

                _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestUpdated, manifestId));
            }
            catch (Exception e)
            {
                _reporter.WriteLine(string.Format(LocalizableStrings.FailedAdManifestUpdate, manifestId, e.Message));
            }
            finally
            {
                if (!string.IsNullOrEmpty(extractionPath) && Directory.Exists(extractionPath))
                {
                    Directory.Delete(extractionPath, true);
                }

                if (!string.IsNullOrEmpty(packagePath) && File.Exists(packagePath) && (offlineCache == null || !offlineCache.HasValue))
                {
                    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);
                    }
                }
            }
        }
        public void InstallWorkloadPack(PackInfo packInfo, SdkFeatureBand sdkFeatureBand, bool useOfflineCache = false)
        {
            if (useOfflineCache)
            {
                throw new NotImplementedException();
            }

            _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))
                    {
                        var packagePath = _nugetPackageInstaller.DownloadPackageAsync(new PackageId(packInfo.Id), new NuGetVersion(packInfo.Version)).Result;
                        tempFilesToDelete.Add(packagePath);

                        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 = _nugetPackageInstaller.ExtractPackageAsync(packagePath, tempExtractionDir).Result;

                            FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(tempExtractionDir, packInfo.Path));
                        }
                    }
                    else
                    {
                        _reporter.WriteLine(string.Format(LocalizableStrings.WorkloadPackAlreadyInstalledMessage, packInfo.Id, packInfo.Version));
                    }

                    WritePackInstallationRecord(packInfo, sdkFeatureBand);
                },
                    rollback: () => {
                    RollBackWorkloadPackInstall(packInfo, sdkFeatureBand);
                });
            }
            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);
                    }
                }
            }
        }
Example #12
0
        private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, bool includePreviews, DirectoryPath?offlineCache = null)
        {
            string packagePath        = null;
            string extractionPath     = null;
            var    manifestId         = new ManifestId(manifest.Id);
            string currentFeatureBand = _sdkFeatureBand.ToString();

            try
            {
                var adManifestPath = GetAdvertisingManifestPath(_sdkFeatureBand, manifestId);

                bool success;
                (success, packagePath) = await GetManifestPackageUpdate(_sdkFeatureBand, manifestId, includePreviews, offlineCache);

                if (!success)
                {
                    if (!(manifest.ManifestFeatureBand).Equals(_sdkFeatureBand))
                    {
                        (success, packagePath) = await GetManifestPackageUpdate(new SdkFeatureBand(manifest.ManifestFeatureBand), manifestId, includePreviews, offlineCache);

                        currentFeatureBand = manifest.ManifestFeatureBand.ToString();
                    }
                }
                if (!success)
                {
                    _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestPackageDoesNotExist, manifestId));
                    return;
                }

                extractionPath = Path.Combine(_tempDirPath, "dotnet-sdk-advertising-temp", $"{manifestId}-extracted");
                Directory.CreateDirectory(extractionPath);
                var resultingFiles = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(extractionPath));

                if (Directory.Exists(adManifestPath))
                {
                    Directory.Delete(adManifestPath, true);
                }
                Directory.CreateDirectory(Path.GetDirectoryName(adManifestPath));
                FileAccessRetrier.RetryOnMoveAccessFailure(() => DirectoryPath.MoveDirectory(Path.Combine(extractionPath, "data"), adManifestPath));

                // add file that contains the advertisted manifest feature band so GetAdvertisingManifestVersionAndWorkloads will use correct feature band, regardless of if rollback occurred or not
                File.WriteAllText(Path.Combine(adManifestPath, "AdvertisedManifestFeatureBand.txt"), currentFeatureBand);

                if (_displayManifestUpdates)
                {
                    _reporter.WriteLine(string.Format(LocalizableStrings.AdManifestUpdated, manifestId));
                }
            }
            catch (Exception e)
            {
                _reporter.WriteLine(string.Format(LocalizableStrings.FailedAdManifestUpdate, manifestId, e.Message));
            }
            finally
            {
                if (!string.IsNullOrEmpty(extractionPath) && Directory.Exists(extractionPath))
                {
                    Directory.Delete(extractionPath, true);
                }

                if (!string.IsNullOrEmpty(packagePath) && File.Exists(packagePath) && (offlineCache == null || !offlineCache.HasValue))
                {
                    File.Delete(packagePath);
                }
                if (!string.IsNullOrEmpty(packagePath) && (offlineCache == null || !offlineCache.HasValue))
                {
                    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);
                        }
                    }
                }
            }
        }
Example #13
0
        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));
            }
        }