예제 #1
0
 private bool HasFeatureBandMarkerFile(string packIdDir, SdkFeatureBand featureBand)
 {
     return(Directory.GetDirectories(packIdDir)
            .SelectMany(packVersionDir => Directory.GetFiles(packVersionDir))
            .Select(featureBandPath => Path.GetFileName(featureBandPath))
            .Any(featureBandFileName => featureBand.ToString().Equals(featureBandFileName)));
 }
예제 #2
0
        public NetSdkManagedInstaller(IReporter reporter,
                                      SdkFeatureBand sdkFeatureBand,
                                      IWorkloadResolver workloadResolver,
                                      string userProfileDir,
                                      INuGetPackageDownloader nugetPackageDownloader = null,
                                      string dotnetDir           = null,
                                      string tempDirPath         = null,
                                      VerbosityOptions verbosity = VerbosityOptions.normal,
                                      PackageSourceLocation packageSourceLocation = null,
                                      RestoreActionConfig restoreActionConfig     = null)
        {
            _userProfileDir  = userProfileDir;
            _dotnetDir       = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath);
            _tempPackagesDir = new DirectoryPath(tempDirPath ?? Path.GetTempPath());
            ILogger logger = verbosity.VerbosityIsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger();

            _restoreActionConfig    = restoreActionConfig;
            _nugetPackageDownloader = nugetPackageDownloader ??
                                      new NuGetPackageDownloader(_tempPackagesDir, filePermissionSetter: null,
                                                                 new FirstPartyNuGetPackageSigningVerifier(_tempPackagesDir), logger,
                                                                 restoreActionConfig: _restoreActionConfig);
            bool userLocal = WorkloadFileBasedInstall.IsUserLocal(_dotnetDir, sdkFeatureBand.ToString());

            _workloadMetadataDir          = Path.Combine(userLocal ? _userProfileDir : _dotnetDir, "metadata", "workloads");
            _reporter                     = reporter;
            _sdkFeatureBand               = sdkFeatureBand;
            _workloadResolver             = workloadResolver;
            _installationRecordRepository = new NetSdkManagedInstallationRecordRepository(_workloadMetadataDir);
            _packageSourceLocation        = packageSourceLocation;
        }
예제 #3
0
        public void GarbageCollectInstalledWorkloadPacks(DirectoryPath?offlineCache = null)
        {
            var installedSdkFeatureBands = _installationRecordRepository.GetFeatureBandsWithInstallationRecords();

            _reporter.WriteLine(string.Format(LocalizableStrings.GarbageCollectingSdkFeatureBandsMessage, string.Join(" ", installedSdkFeatureBands)));
            var    currentBandInstallRecords = GetExpectedPackInstallRecords(_sdkFeatureBand);
            string installedPacksDir         = Path.Combine(_workloadMetadataDir, InstalledPacksDir, "v1");

            if (!Directory.Exists(installedPacksDir))
            {
                return;
            }

            foreach (var packIdDir in Directory.GetDirectories(installedPacksDir))
            {
                foreach (var packVersionDir in Directory.GetDirectories(packIdDir))
                {
                    var bandRecords = Directory.GetFileSystemEntries(packVersionDir);

                    var unneededBandRecords = bandRecords
                                              .Where(recordPath => !installedSdkFeatureBands.Contains(new SdkFeatureBand(Path.GetFileName(recordPath))));

                    var currentBandRecordPath = Path.Combine(packVersionDir, _sdkFeatureBand.ToString());
                    if (bandRecords.Contains(currentBandRecordPath) && !currentBandInstallRecords.Contains(currentBandRecordPath))
                    {
                        unneededBandRecords = unneededBandRecords.Append(currentBandRecordPath);
                    }

                    if (!unneededBandRecords.Any())
                    {
                        continue;
                    }

                    // Save the pack info in case we need to delete the pack
                    var jsonPackInfo = File.ReadAllText(unneededBandRecords.First());
                    foreach (var unneededRecord in unneededBandRecords)
                    {
                        File.Delete(unneededRecord);
                    }

                    if (!bandRecords.Except(unneededBandRecords).Any())
                    {
                        Directory.Delete(packVersionDir);
                        var deletablePack = GetPackInfo(packVersionDir);
                        if (deletablePack == null)
                        {
                            // Pack no longer exists in manifests, get pack info from installation record
                            deletablePack = JsonSerializer.Deserialize(jsonPackInfo, typeof(PackInfo)) as PackInfo;
                        }
                        DeletePack(deletablePack);
                    }
                }

                if (!Directory.GetFileSystemEntries(packIdDir).Any())
                {
                    Directory.Delete(packIdDir);
                }
            }
        }
        public void DeleteWorkloadInstallationRecord(WorkloadId workloadId, SdkFeatureBand featureBand)
        {
            var path = Path.Combine(_workloadMetadataDir, featureBand.ToString(), _installedWorkloadDir, workloadId.ToString());

            if (File.Exists(path))
            {
                File.Delete(path);
            }
        }
        public void WriteWorkloadInstallationRecord(WorkloadId workloadId, SdkFeatureBand featureBand)
        {
            _reporter.WriteLine(string.Format(LocalizableStrings.WritingWorkloadInstallRecordMessage, workloadId));
            var path = Path.Combine(_workloadMetadataDir, featureBand.ToString(), _installedWorkloadDir, workloadId.ToString());

            if (!Directory.Exists(Path.GetDirectoryName(path)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }
            File.Create(path);
        }
예제 #6
0
 public IEnumerable <WorkloadId> GetUpdatableWorkloadsToAdvertise(IEnumerable <WorkloadId> installedWorkloads)
 {
     try
     {
         var overlayProvider             = new TempDirectoryWorkloadManifestProvider(Path.Combine(_userProfileDir, "sdk-advertising", _sdkFeatureBand.ToString()), _sdkFeatureBand.ToString());
         var advertisingManifestResolver = _workloadResolver.CreateOverlayResolver(overlayProvider);
         return(_workloadResolver.GetUpdatedWorkloads(advertisingManifestResolver, installedWorkloads));
     }
     catch
     {
         return(Array.Empty <WorkloadId>());
     }
 }
        public IEnumerable <string> GetInstalledWorkloads(SdkFeatureBand featureBand)
        {
            var path = Path.Combine(_workloadMetadataDir, featureBand.ToString(), _installedWorkloadDir);

            if (Directory.Exists(path))
            {
                return(Directory.EnumerateFiles(path)
                       .Select(file => Path.GetFileName(file)));
            }
            else
            {
                return(new List <string>());
            }
        }
        public void GarbageCollectInstalledWorkloadPacks()
        {
            var installedPacksDir        = Path.Combine(_workloadMetadataDir, _installedPacksDir, "v1");
            var installedSdkFeatureBands = GetFeatureBandsWithInstallationRecords();

            _reporter.WriteLine(string.Format(LocalizableStrings.GarbageCollectingSdkFeatureBandsMessage, string.Join(" ", installedSdkFeatureBands)));
            var currentBandInstallRecords = GetExpectedPackInstallRecords(_sdkFeatureBand);

            foreach (var packIdDir in Directory.GetDirectories(installedPacksDir))
            {
                foreach (var packVersionDir in Directory.GetDirectories(packIdDir))
                {
                    var bandRecords = Directory.GetFileSystemEntries(packVersionDir);

                    var unneededBandRecords = bandRecords
                                              .Where(recordPath => !installedSdkFeatureBands.Contains(new SdkFeatureBand(Path.GetFileName(recordPath))));

                    var currentBandRecordPath = Path.Combine(packVersionDir, _sdkFeatureBand.ToString());
                    if (bandRecords.Contains(currentBandRecordPath) && !currentBandInstallRecords.Contains(currentBandRecordPath))
                    {
                        unneededBandRecords = unneededBandRecords.Append(currentBandRecordPath);
                    }

                    foreach (var unneededRecord in unneededBandRecords)
                    {
                        File.Delete(unneededRecord);
                    }

                    if (!bandRecords.Except(unneededBandRecords).Any())
                    {
                        Directory.Delete(packVersionDir);
                        var deletablePack = GetPackInfo(packVersionDir);
                        DeletePack(deletablePack);
                    }
                }

                if (!Directory.GetFileSystemEntries(packIdDir).Any())
                {
                    Directory.Delete(packIdDir);
                }
            }
        }
예제 #9
0
 private string GetPackInstallRecordPath(PackInfo packInfo, SdkFeatureBand featureBand) =>
 Path.Combine(_workloadMetadataDir, InstalledPacksDir, "v1", packInfo.Id, packInfo.Version, featureBand.ToString());
예제 #10
0
        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));
            }
        }
예제 #11
0
 private string GetAdvertisingManifestPath(SdkFeatureBand featureBand, ManifestId manifestId) =>
 Path.Combine(_userHome, ".dotnet", "sdk-advertising", featureBand.ToString(), manifestId.ToString());
예제 #12
0
 private string GetAdvertisingManifestPath(SdkFeatureBand featureBand, ManifestId manifestId) =>
 Path.Combine(_userProfileDir, "sdk-advertising", featureBand.ToString(), manifestId.ToString());
예제 #13
0
        public static IInstaller GetWorkloadInstaller(
            IReporter reporter,
            SdkFeatureBand sdkFeatureBand,
            IWorkloadResolver workloadResolver,
            VerbosityOptions verbosity,
            string userProfileDir,
            bool verifySignatures,
            INuGetPackageDownloader nugetPackageDownloader = null,
            string dotnetDir   = null,
            string tempDirPath = null,
            PackageSourceLocation packageSourceLocation = null,
            RestoreActionConfig restoreActionConfig     = null,
            bool elevationRequired = true)
        {
            dotnetDir = string.IsNullOrWhiteSpace(dotnetDir) ? Path.GetDirectoryName(Environment.ProcessPath) : dotnetDir;
            var installType = GetWorkloadInstallType(sdkFeatureBand, dotnetDir);

            if (installType == InstallType.Msi)
            {
                if (!OperatingSystem.IsWindows())
                {
                    throw new InvalidOperationException(LocalizableStrings.OSDoesNotSupportMsi);
                }

                return(NetSdkMsiInstallerClient.Create(verifySignatures, sdkFeatureBand, workloadResolver,
                                                       nugetPackageDownloader, verbosity, packageSourceLocation, reporter, tempDirPath));
            }

            if (elevationRequired && !WorkloadFileBasedInstall.IsUserLocal(dotnetDir, sdkFeatureBand.ToString()) && !CanWriteToDotnetRoot(dotnetDir))
            {
                throw new GracefulException(LocalizableStrings.InadequatePermissions, isUserError: false);
            }

            userProfileDir ??= CliFolderPathCalculator.DotnetUserProfileFolderPath;

            return(new FileBasedInstaller(reporter,
                                          sdkFeatureBand,
                                          workloadResolver,
                                          userProfileDir,
                                          nugetPackageDownloader,
                                          dotnetDir: dotnetDir,
                                          tempDirPath: tempDirPath,
                                          verbosity: verbosity,
                                          packageSourceLocation: packageSourceLocation,
                                          restoreActionConfig: restoreActionConfig));
        }
예제 #14
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));
            }
        }