Example #1
0
        public async Task ExtractManifestPackagesToTempDirAsync(IEnumerable <string> manifestPackages, DirectoryPath tempDir)
        {
            Directory.CreateDirectory(tempDir.Value);
            foreach (var manifestPackagePath in manifestPackages)
            {
                var manifestId    = Path.GetFileNameWithoutExtension(manifestPackagePath);
                var extractionDir = Path.Combine(tempDir.Value, manifestId);
                Directory.CreateDirectory(extractionDir);
                await _nugetPackageDownloader.ExtractPackageAsync(manifestPackagePath, new DirectoryPath(extractionDir));

                File.Copy(Path.Combine(extractionDir, "data", "WorkloadManifest.json"), Path.Combine(tempDir.Value, manifestId, "WorkloadManifest.json"));
            }
        }
Example #2
0
        /// <summary>
        /// Extracts the MSI and JSON manifest using the NuGet package in the offline cache to a temporary
        /// folder or downloads a copy before extracting it.
        /// </summary>
        /// <param name="packageId">The ID of the package to download.</param>
        /// <param name="packageVersion">The version of the package to download.</param>
        /// <param name="offlineCache">The path of the offline package cache. If <see langword="null"/>, the package
        /// is downloaded.</param>
        /// <returns>The directory where the package was extracted.</returns>
        /// <exception cref="FileNotFoundException" />
        private string ExtractPackage(string packageId, string packageVersion, DirectoryPath?offlineCache)
        {
            string packagePath;

            if (offlineCache == null || !offlineCache.HasValue)
            {
                Reporter.WriteLine($"Downloading {packageId} ({packageVersion})");
                packagePath = _nugetPackageDownloader.DownloadPackageAsync(new PackageId(packageId), new NuGetVersion(packageVersion),
                                                                           _packageSourceLocation).Result;
                Log?.LogMessage($"Downloaded {packageId} ({packageVersion}) to '{packagePath}");
            }
            else
            {
                packagePath = Path.Combine(offlineCache.Value.Value, $"{packageId}.{packageVersion}.nupkg");
                Log?.LogMessage($"Using offline cache, package: {packagePath}");
            }

            if (!File.Exists(packagePath))
            {
                throw new FileNotFoundException(string.Format(LocalizableStrings.CacheMissingPackage, packageId, packageVersion, offlineCache));
            }

            // Extract the contents to a random folder to avoid potential file injection/hijacking
            // shenanigans before moving it to the final cache directory.
            string extractionDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            Directory.CreateDirectory(extractionDirectory);
            Log?.LogMessage($"Extracting '{packageId}' to '{extractionDirectory}'");
            _ = _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(extractionDirectory)).Result;

            return(extractionDirectory);
        }
Example #3
0
        public async Task <string> ResolveAppHostSourceDirectoryAsync(string archOption, string targetFramework)
        {
            string rid;
            var    validRids = new string[] { "win-x64", "win-arm64", "osx-x64", "osx-arm64" };

            if (string.IsNullOrEmpty(archOption))
            {
                if (!string.IsNullOrEmpty(targetFramework) && new NuGetFramework(targetFramework).Version < new Version("6.0") &&
                    (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS()) && !RuntimeInformation.ProcessArchitecture.Equals(Architecture.X64))
                {
                    rid = OperatingSystem.IsWindows() ? "win-x64" : "osx-x64";
                }
                else
                {
                    // Use the default app host
                    return(GetDefaultAppHostSourceDirectory());
                }
            }
            else
            {
                rid = CommonOptions.ResolveRidShorthandOptionsToRuntimeIdentifier(null, archOption);
            }

            if (!validRids.Contains(rid))
            {
                throw new GracefulException(string.Format(LocalizableStrings.InvalidRuntimeIdentifier, rid, string.Join(" ", validRids)));
            }

            var packageId   = new PackageId($"microsoft.netcore.app.host.{rid}");
            var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, packageSourceLocation : _packageSourceLocation);

            var content = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, _tempDir);

            return(Path.Combine(_tempDir.Value, "runtimes", rid, "native"));
        }
Example #4
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);
                    }
                }
            }
        }
        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 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);
                    }
                }
            }
        }