示例#1
0
        private IEnumerable <string> GetExpectedPackInstallRecords(SdkFeatureBand sdkFeatureBand)
        {
            var installedWorkloads = _installationRecordRepository.GetInstalledWorkloads(sdkFeatureBand);

            return(installedWorkloads
                   .SelectMany(workload => _workloadResolver.GetPacksInWorkload(workload.ToString()))
                   .Select(pack => _workloadResolver.TryGetPackInfo(pack))
                   .Where(pack => pack != null)
                   .Select(packInfo => GetPackInstallRecordPath(packInfo, sdkFeatureBand)));
        }
示例#2
0
 public static IInstaller GetWorkloadInstaller(
     IReporter reporter,
     SdkFeatureBand sdkFeatureBand,
     IWorkloadResolver workloadResolver,
     VerbosityOptions verbosity,
     INuGetPackageDownloader nugetPackageDownloader = null,
     string dotnetDir = null)
 {
     return(new NetSdkManagedInstaller(reporter, sdkFeatureBand, workloadResolver, nugetPackageDownloader, verbosity: verbosity, dotnetDir: dotnetDir));
 }
        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);
        }
示例#4
0
        private void WritePackInstallationRecord(PackInfo packInfo, SdkFeatureBand featureBand)
        {
            _reporter.WriteLine(string.Format(LocalizableStrings.WritingPackInstallRecordMessage, packInfo.Id, packInfo.Version));
            var path = GetPackInstallRecordPath(packInfo, featureBand);

            if (!Directory.Exists(Path.GetDirectoryName(path)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }
            File.WriteAllText(path, JsonSerializer.Serialize(packInfo));
        }
示例#5
0
        /// <summary>
        /// Determines the <see cref="InstallType"/> associated with a specific SDK version.
        /// </summary>
        /// <param name="sdkFeatureBand">The SDK version to check.</param>
        /// <returns>The <see cref="InstallType"/> associated with the SDK.</returns>
        public static InstallType GetWorkloadInstallType(SdkFeatureBand sdkFeatureBand, string dotnetDir)
        {
            string installerTypePath = Path.Combine(dotnetDir, "metadata",
                                                    "workloads", $"{sdkFeatureBand}", "installertype");

            if (File.Exists(Path.Combine(installerTypePath, "msi")))
            {
                return(InstallType.Msi);
            }

            return(InstallType.FileBased);
        }
示例#6
0
 public WorkloadManifestUpdater(
     IReporter reporter,
     IWorkloadManifestProvider workloadManifestProvider,
     INuGetPackageDownloader nugetPackageDownloader,
     string userHome)
 {
     _reporter = reporter;
     _workloadManifestProvider = workloadManifestProvider;
     _userHome = userHome;
     _nugetPackageDownloader = nugetPackageDownloader;
     _sdkFeatureBand         = new SdkFeatureBand(_workloadManifestProvider.GetSdkFeatureBand());
 }
示例#7
0
        public WorkloadInstallCommand(
            ParseResult parseResult,
            IReporter reporter = null,
            IWorkloadResolver workloadResolver               = null,
            IInstaller workloadInstaller                     = null,
            INuGetPackageDownloader nugetPackageDownloader   = null,
            IWorkloadManifestUpdater workloadManifestUpdater = null,
            string dotnetDir      = null,
            string userProfileDir = null,
            string tempDirPath    = null,
            string version        = null,
            IReadOnlyCollection <string> workloadIds = null)
            : base(parseResult, reporter: reporter, tempDirPath: tempDirPath, nugetPackageDownloader: nugetPackageDownloader)
        {
            _skipManifestUpdate     = parseResult.GetValueForOption(WorkloadInstallCommandParser.SkipManifestUpdateOption);
            _includePreviews        = parseResult.GetValueForOption(WorkloadInstallCommandParser.IncludePreviewOption);
            _printDownloadLinkOnly  = parseResult.GetValueForOption(WorkloadInstallCommandParser.PrintDownloadLinkOnlyOption);
            _fromCacheOption        = parseResult.GetValueForOption(WorkloadInstallCommandParser.FromCacheOption);
            _downloadToCacheOption  = parseResult.GetValueForOption(WorkloadInstallCommandParser.DownloadToCacheOption);
            _workloadIds            = workloadIds ?? parseResult.GetValueForArgument(WorkloadInstallCommandParser.WorkloadIdArgument).ToList().AsReadOnly();
            _dotnetPath             = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath);
            _userProfileDir         = userProfileDir ?? CliFolderPathCalculator.DotnetUserProfileFolderPath;
            _sdkVersion             = WorkloadOptionsExtensions.GetValidatedSdkVersion(parseResult.GetValueForOption(WorkloadInstallCommandParser.VersionOption), version, _dotnetPath, _userProfileDir);
            _sdkFeatureBand         = new SdkFeatureBand(_sdkVersion);
            _fromRollbackDefinition = parseResult.GetValueForOption(WorkloadInstallCommandParser.FromRollbackFileOption);

            var configOption = parseResult.GetValueForOption(WorkloadInstallCommandParser.ConfigOption);
            var sourceOption = parseResult.GetValueForOption(WorkloadInstallCommandParser.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, _sdkVersion.ToString(), userProfileDir);

            _workloadResolver = workloadResolver ?? WorkloadResolver.Create(sdkWorkloadManifestProvider, _dotnetPath, _sdkVersion.ToString(), _userProfileDir);
            var sdkFeatureBand  = new SdkFeatureBand(_sdkVersion);
            var tempPackagesDir = new DirectoryPath(Path.Combine(TempDirectoryPath, "dotnet-sdk-advertising-temp"));

            _workloadInstaller = workloadInstaller ??
                                 WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, sdkFeatureBand,
                                                                               _workloadResolver, Verbosity, _userProfileDir, VerifySignatures, PackageDownloader, _dotnetPath, TempDirectoryPath,
                                                                               _packageSourceLocation, RestoreActionConfiguration, elevationRequired: !_printDownloadLinkOnly && string.IsNullOrWhiteSpace(_downloadToCacheOption));
            bool displayManifestUpdates = false;

            if (Verbosity.VerbosityIsDetailedOrDiagnostic())
            {
                displayManifestUpdates = true;
            }
            _workloadManifestUpdater = workloadManifestUpdater ?? new WorkloadManifestUpdater(Reporter, _workloadResolver, PackageDownloader, _userProfileDir, TempDirectoryPath,
                                                                                              _workloadInstaller.GetWorkloadInstallationRecordRepository(), _packageSourceLocation, displayManifestUpdates: displayManifestUpdates);

            ValidateWorkloadIdsInput();
        }
示例#8
0
        public IEnumerable <(WorkloadPackId, string)> GetInstalledPacks(SdkFeatureBand sdkFeatureBand)
        {
            var installedPacksDir = Path.Combine(_workloadMetadataDir, InstalledPacksDir, "v1");

            if (!Directory.Exists(installedPacksDir))
            {
                return(Enumerable.Empty <(WorkloadPackId, string)>());
            }
            return(Directory.GetDirectories(installedPacksDir)
                   .Where(packIdDir => HasFeatureBandMarkerFile(packIdDir, sdkFeatureBand))
                   .SelectMany(packIdPath => Directory.GetDirectories(packIdPath))
                   .Select(packVersionPath => (new WorkloadPackId(Path.GetFileName(Path.GetDirectoryName(packVersionPath))), Path.GetFileName(packVersionPath))));
        }
示例#9
0
        private string GetOfflinePackagePath(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, DirectoryPath?offlineCache = null)
        {
            string packagePath = Directory.GetFiles(offlineCache.Value.Value)
                                 .Where(path => path.EndsWith(".nupkg"))
                                 .Where(path =>
            {
                var manifestPackageId = GetManifestPackageId(sdkFeatureBand, manifestId).ToString();
                return(Path.GetFileName(path).StartsWith(manifestPackageId, StringComparison.OrdinalIgnoreCase));
            })
                                 .Max();

            return(packagePath);
        }
        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 NetSdkManagedInstaller(
     IReporter reporter,
     SdkFeatureBand sdkFeatureBand,
     IWorkloadResolver workloadResolver,
     INuGetPackageDownloader nugetPackageDownloader = null,
     string dotnetDir = null)
 {
     _dotnetDir             = dotnetDir ?? EnvironmentProvider.GetDotnetExeDirectory();
     _tempPackagesDir       = new DirectoryPath(Path.Combine(_dotnetDir, "metadata", "temp"));
     _nugetPackageInstaller = nugetPackageDownloader ?? new NuGetPackageDownloader(_tempPackagesDir);
     _workloadMetadataDir   = Path.Combine(_dotnetDir, "metadata", "workloads");
     _reporter         = reporter;
     _sdkFeatureBand   = sdkFeatureBand;
     _workloadResolver = workloadResolver;
 }
示例#12
0
 public NetSdkManagedInstaller(
     IReporter reporter,
     SdkFeatureBand sdkFeatureBand,
     IWorkloadResolver workloadResolver,
     INuGetPackageDownloader nugetPackageDownloader = null,
     string dotnetDir = null)
 {
     _dotnetDir             = dotnetDir ?? EnvironmentProvider.GetDotnetExeDirectory();
     _tempPackagesDir       = Path.Combine(_dotnetDir, "metadata", "temp");
     _nugetPackageInstaller = nugetPackageDownloader ?? new NuGetPackageDownloader(_tempPackagesDir, sourceUrl: "https://pkgs.dev.azure.com/azure-public/vside/_packaging/xamarin-impl/nuget/v3/index.json");
     _workloadMetadataDir   = Path.Combine(_dotnetDir, "metadata", "workloads");
     _reporter         = reporter;
     _sdkFeatureBand   = sdkFeatureBand;
     _workloadResolver = workloadResolver;
 }
示例#13
0
 public WorkloadManifestUpdater(
     IReporter reporter,
     IWorkloadManifestProvider workloadManifestProvider,
     INuGetPackageDownloader nugetPackageDownloader,
     string userHome,
     string tempDirPath,
     PackageSourceLocation packageSourceLocation = null)
 {
     _reporter = reporter;
     _workloadManifestProvider = workloadManifestProvider;
     _userHome               = userHome;
     _tempDirPath            = tempDirPath;
     _nugetPackageDownloader = nugetPackageDownloader;
     _sdkFeatureBand         = new SdkFeatureBand(_workloadManifestProvider.GetSdkFeatureBand());
     _packageSourceLocation  = packageSourceLocation;
 }
示例#14
0
        public WorkloadInstallCommand(
            ParseResult parseResult,
            IReporter reporter = null,
            IWorkloadResolver workloadResolver               = null,
            IInstaller workloadInstaller                     = null,
            INuGetPackageDownloader nugetPackageDownloader   = null,
            IWorkloadManifestUpdater workloadManifestUpdater = null,
            string dotnetDir   = null,
            string userHome    = null,
            string tempDirPath = null,
            string version     = null)
            : base(parseResult)
        {
            _reporter              = reporter ?? Reporter.Output;
            _skipManifestUpdate    = parseResult.ValueForOption <bool>(WorkloadInstallCommandParser.SkipManifestUpdateOption);
            _includePreviews       = parseResult.ValueForOption <bool>(WorkloadInstallCommandParser.IncludePreviewOption);
            _printDownloadLinkOnly = parseResult.ValueForOption <bool>(WorkloadInstallCommandParser.PrintDownloadLinkOnlyOption);
            _fromCacheOption       = parseResult.ValueForOption <string>(WorkloadInstallCommandParser.FromCacheOption);
            _downloadToCacheOption = parseResult.ValueForOption <string>(WorkloadInstallCommandParser.DownloadToCacheOption);
            _workloadIds           = parseResult.ValueForArgument <IEnumerable <string> >(WorkloadInstallCommandParser.WorkloadIdArgument).ToList().AsReadOnly();
            _verbosity             = parseResult.ValueForOption <VerbosityOptions>(WorkloadInstallCommandParser.VerbosityOption);
            _sdkVersion            = string.IsNullOrEmpty(parseResult.ValueForOption <string>(WorkloadInstallCommandParser.VersionOption)) ?
                                     new ReleaseVersion(version ?? Product.Version) :
                                     new ReleaseVersion(parseResult.ValueForOption <string>(WorkloadInstallCommandParser.VersionOption));
            _tempDirPath = tempDirPath ?? (string.IsNullOrWhiteSpace(parseResult.ValueForOption <string>(WorkloadInstallCommandParser.TempDirOption)) ?
                                           Path.GetTempPath() :
                                           parseResult.ValueForOption <string>(WorkloadInstallCommandParser.TempDirOption));

            var configOption    = parseResult.ValueForOption <string>(WorkloadInstallCommandParser.ConfigOption);
            var addSourceOption = parseResult.ValueForOption <string[]>(WorkloadInstallCommandParser.AddSourceOption);

            _packageSourceLocation = string.IsNullOrEmpty(configOption) && (addSourceOption == null || !addSourceOption.Any()) ? null :
                                     new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), sourceFeedOverrides: addSourceOption);

            _dotnetPath = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath);
            _workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _sdkVersion.ToString());
            _workloadResolver         = workloadResolver ?? WorkloadResolver.Create(_workloadManifestProvider, _dotnetPath, _sdkVersion.ToString());
            var sdkFeatureBand = new SdkFeatureBand(_sdkVersion);

            _workloadInstaller = workloadInstaller ??
                                 WorkloadInstallerFactory.GetWorkloadInstaller(_reporter, sdkFeatureBand, _workloadResolver, _verbosity, nugetPackageDownloader, _dotnetPath, _packageSourceLocation);
            _userHome = userHome ?? CliFolderPathCalculator.DotnetHomePath;
            var tempPackagesDir = new DirectoryPath(Path.Combine(_tempDirPath, "dotnet-sdk-advertising-temp"));

            _nugetPackageDownloader  = nugetPackageDownloader ?? new NuGetPackageDownloader(tempPackagesDir, filePermissionSetter: null, new NullLogger());
            _workloadManifestUpdater = workloadManifestUpdater ?? new WorkloadManifestUpdater(_reporter, _workloadManifestProvider, _nugetPackageDownloader, _userHome, _tempDirPath, _packageSourceLocation);
        }
示例#15
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));
        }
示例#16
0
        public void RollBackWorkloadPackInstall(PackInfo packInfo, SdkFeatureBand sdkFeatureBand, DirectoryPath?offlineCache = null)
        {
            try
            {
                ReportPendingReboot();
                Log?.LogMessage($"Rolling back workload pack installation for {packInfo.ResolvedPackageId}.");

                // Determine the MSI payload package ID based on the host architecture, pack ID and pack version.
                string msiPackageId = GetMsiPackageId(packInfo);

                // Retrieve the payload from the MSI package cache.
                MsiPayload msi = GetCachedMsiPayload(msiPackageId, packInfo.Version, offlineCache);
                VerifyPackage(msi);

                // Check the provider key first in case we were installed and we only need to remove
                // a dependent.
                DependencyProvider depProvider = new DependencyProvider(msi.Manifest.ProviderKeyName);

                // Try and remove the dependent against this SDK. If any remain we'll simply exit.
                UpdateDependent(InstallRequestType.RemoveDependent, msi.Manifest.ProviderKeyName, _dependent);

                if (depProvider.Dependents.Any())
                {
                    Log?.LogMessage($"Cannot remove pack, other dependents remain: {string.Join(", ", depProvider.Dependents)}.");
                    return;
                }

                // Make sure the MSI is actually installed.
                DetectState   state         = DetectPackage(msi, out Version installedVersion);
                InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Uninstall, installedVersion, out _);

                // The previous steps would have logged the final action. If the verdict is not to uninstall we can exit.
                if (plannedAction == InstallAction.Uninstall)
                {
                    ExecutePackage(msi, plannedAction);
                }

                Log?.LogMessage("Rollback completed.");
            }
            catch (Exception e)
            {
                LogException(e);
                throw;
            }
        }
示例#17
0
 public NetSdkManagedInstaller(
     IReporter reporter,
     SdkFeatureBand sdkFeatureBand,
     IWorkloadResolver workloadResolver,
     INuGetPackageDownloader nugetPackageDownloader = null,
     string dotnetDir           = null,
     VerbosityOptions verbosity = VerbosityOptions.normal)
 {
     _dotnetDir              = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath);
     _tempPackagesDir        = new DirectoryPath(Path.Combine(_dotnetDir, "metadata", "temp"));
     _nugetPackageDownloader = nugetPackageDownloader ??
                               new NuGetPackageDownloader(_tempPackagesDir, filePermissionSetter: null, verbosity.VerbosityIsDetailedOrDiagnostic() ? new NuGetConsoleLogger() : new NullLogger());
     _workloadMetadataDir          = Path.Combine(_dotnetDir, "metadata", "workloads");
     _reporter                     = reporter;
     _sdkFeatureBand               = sdkFeatureBand;
     _workloadResolver             = workloadResolver;
     _installationRecordRepository = new NetSdkManagedInstallationRecordRepository(_dotnetDir);
 }
示例#18
0
        private IEnumerable <(ManifestId id, ManifestVersion version, SdkFeatureBand featureBand)> ParseRollbackDefinitionFile(string rollbackDefinitionFilePath)
        {
            string fileContent;

            if (Uri.TryCreate(rollbackDefinitionFilePath, UriKind.Absolute, out var rollbackUri) && !rollbackUri.IsFile)
            {
                fileContent = (new HttpClient()).GetStringAsync(rollbackDefinitionFilePath).Result;
            }
            else
            {
                if (File.Exists(rollbackDefinitionFilePath))
                {
                    fileContent = File.ReadAllText(rollbackDefinitionFilePath);
                }
                else
                {
                    throw new ArgumentException(string.Format(LocalizableStrings.RollbackDefinitionFileDoesNotExist, rollbackDefinitionFilePath));
                }
            }
            return(JsonSerializer.Deserialize <IDictionary <string, string> >(fileContent)
                   .Select(manifest =>
            {
                ManifestVersion manifestVersion;
                SdkFeatureBand manifestFeatureBand;
                var parts = manifest.Value.Split('/');

                string manifestVersionString = (parts[0]);
                if (!FXVersion.TryParse(manifestVersionString, out FXVersion version))
                {
                    throw new FormatException(String.Format(LocalizableStrings.InvalidVersionForWorkload, manifest.Key, manifestVersionString));
                }

                manifestVersion = new ManifestVersion(parts[0]);
                if (parts.Length == 1)
                {
                    manifestFeatureBand = _sdkFeatureBand;
                }
                else
                {
                    manifestFeatureBand = new SdkFeatureBand(parts[1]);
                }
                return (new ManifestId(manifest.Key), manifestVersion, manifestFeatureBand);
            }));
        }
示例#19
0
 public WorkloadManifestUpdater(IReporter reporter,
                                IWorkloadResolver workloadResolver,
                                INuGetPackageDownloader nugetPackageDownloader,
                                string userProfileDir,
                                string tempDirPath,
                                IWorkloadInstallationRecordRepository workloadRecordRepo,
                                PackageSourceLocation packageSourceLocation  = null,
                                Func <string, string> getEnvironmentVariable = null)
 {
     _reporter               = reporter;
     _workloadResolver       = workloadResolver;
     _userProfileDir         = userProfileDir;
     _tempDirPath            = tempDirPath;
     _nugetPackageDownloader = nugetPackageDownloader;
     _sdkFeatureBand         = new SdkFeatureBand(_workloadResolver.GetSdkFeatureBand());
     _packageSourceLocation  = packageSourceLocation;
     _getEnvironmentVariable = getEnvironmentVariable ?? Environment.GetEnvironmentVariable;
     _workloadRecordRepo     = workloadRecordRepo;
 }
示例#20
0
 public WorkloadManifestUpdater(IReporter reporter,
                                IWorkloadManifestProvider workloadManifestProvider,
                                IWorkloadResolver workloadResolver,
                                INuGetPackageDownloader nugetPackageDownloader,
                                string userHome,
                                string tempDirPath,
                                PackageSourceLocation packageSourceLocation  = null,
                                Func <string, string> getEnvironmentVariable = null)
 {
     _reporter = reporter;
     _workloadManifestProvider = workloadManifestProvider;
     _workloadResolver         = workloadResolver;
     _userHome               = userHome;
     _tempDirPath            = tempDirPath;
     _nugetPackageDownloader = nugetPackageDownloader;
     _sdkFeatureBand         = new SdkFeatureBand(_workloadManifestProvider.GetSdkFeatureBand());
     _packageSourceLocation  = packageSourceLocation;
     _getEnvironmentVariable = getEnvironmentVariable ?? Environment.GetEnvironmentVariable;
 }
示例#21
0
        public static IInstaller GetWorkloadInstaller(
            IReporter reporter,
            SdkFeatureBand sdkFeatureBand,
            IWorkloadResolver workloadResolver,
            VerbosityOptions verbosity,
            INuGetPackageDownloader nugetPackageDownloader = null,
            string dotnetDir   = null,
            string tempDirPath = null,
            PackageSourceLocation packageSourceLocation = null,
            RestoreActionConfig restoreActionConfig     = null,
            bool elevationRequired = true)
        {
            var installType = GetWorkloadInstallType(sdkFeatureBand, string.IsNullOrWhiteSpace(dotnetDir)
                ? Path.GetDirectoryName(Environment.ProcessPath)
                : dotnetDir);

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

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

            if (elevationRequired && !CanWriteToDotnetRoot(dotnetDir))
            {
                throw new GracefulException(LocalizableStrings.InadequatePermissions);
            }

            return(new NetSdkManagedInstaller(reporter,
                                              sdkFeatureBand,
                                              workloadResolver,
                                              nugetPackageDownloader,
                                              dotnetDir: dotnetDir,
                                              tempDirPath: tempDirPath,
                                              verbosity: verbosity,
                                              packageSourceLocation: packageSourceLocation,
                                              restoreActionConfig: restoreActionConfig));
        }
示例#22
0
        private async Task <(bool, string)> GetManifestPackageUpdate(SdkFeatureBand sdkFeatureBand, ManifestId manifestId, bool includePreviews, DirectoryPath?offlineCache = null)
        {
            if (offlineCache == null || !offlineCache.HasValue)
            {
                try
                {
                    string packagePath = await GetOnlinePackagePath(sdkFeatureBand, manifestId, includePreviews);

                    return(true, packagePath);
                }
                catch (NuGetPackageNotFoundException)
                {
                    return(false, null);
                }
            }
            else
            {
                string packagePath = GetOfflinePackagePath(sdkFeatureBand, manifestId, offlineCache);
                return(packagePath != null, packagePath);
            }
        }
示例#23
0
        private void DeletePackInstallationRecord(PackInfo packInfo, SdkFeatureBand featureBand)
        {
            var packInstallRecord = GetPackInstallRecordPath(packInfo, featureBand);

            if (File.Exists(packInstallRecord))
            {
                File.Delete(packInstallRecord);

                var packRecordVersionDir = Path.GetDirectoryName(packInstallRecord);
                if (!Directory.GetFileSystemEntries(packRecordVersionDir).Any())
                {
                    Directory.Delete(packRecordVersionDir);

                    var packRecordIdDir = Path.GetDirectoryName(packRecordVersionDir);
                    if (!Directory.GetFileSystemEntries(packRecordIdDir).Any())
                    {
                        Directory.Delete(packRecordIdDir);
                    }
                }
            }
        }
示例#24
0
        public void InstallWorkloads(IEnumerable <WorkloadId> workloadIds, bool skipManifestUpdate = false)
        {
            _reporter.WriteLine();
            var featureBand = new SdkFeatureBand(string.Join('.', _sdkVersion.Major, _sdkVersion.Minor, _sdkVersion.SdkFeatureBand));

            if (!skipManifestUpdate)
            {
                throw new NotImplementedException();
            }

            InstallWorkloadsWithInstallRecord(workloadIds, featureBand);

            if (_workloadInstaller.GetInstallationUnit().Equals(InstallationUnit.Packs))
            {
                _workloadInstaller.GetPackInstaller().GarbageCollectInstalledWorkloadPacks();
            }

            _reporter.WriteLine();
            _reporter.WriteLine(string.Format(LocalizableStrings.InstallationSucceeded, string.Join(" ", workloadIds)));
            _reporter.WriteLine();
        }
示例#25
0
 public static void AdvertiseWorkloadUpdates()
 {
     try
     {
         var            backgroundUpdatesDisabled = bool.TryParse(Environment.GetEnvironmentVariable(EnvironmentVariableNames.WORKLOAD_UPDATE_NOTIFY_DISABLE), out var disableEnvVar) && disableEnvVar;
         SdkFeatureBand featureBand   = new SdkFeatureBand(Product.Version);
         var            adUpdatesFile = GetAdvertisingWorkloadsFilePath(CliFolderPathCalculator.DotnetUserProfileFolderPath, featureBand);
         if (!backgroundUpdatesDisabled && File.Exists(adUpdatesFile))
         {
             var updatableWorkloads = JsonSerializer.Deserialize <string[]>(File.ReadAllText(adUpdatesFile));
             if (updatableWorkloads != null && updatableWorkloads.Any())
             {
                 Console.WriteLine();
                 Console.WriteLine(LocalizableStrings.WorkloadUpdatesAvailable);
             }
         }
     }
     catch (Exception)
     {
         // Never surface errors
     }
 }
示例#26
0
        public void InstallWorkloadPack(PackInfo packInfo, SdkFeatureBand sdkFeatureBand, DirectoryPath?offlineCache = null)
        {
            try
            {
                // Determine the MSI payload package ID based on the host architecture, pack ID and pack version.
                string msiPackageId = GetMsiPackageId(packInfo);

                // Retrieve the payload from the MSI package cache.
                MsiPayload msiPayload = GetCachedMsiPayload(msiPackageId, packInfo.Version);
                VerifyPackage(msiPayload);
                DetectState state = Detect(msiPayload.Manifest.ProductCode, out string _);
                PlanAndExecute(msiPayload, packInfo, state, InstallAction.Install);

                // Update the reference count against the MSI.
                UpdateDependent(InstallRequestType.AddDependent, msiPayload.Manifest.ProviderKeyName, _dependent);
            }
            catch (Exception e)
            {
                LogException(e);
                throw;
            }
        }
示例#27
0
        public WorkloadInstallCommand(
            ParseResult parseResult,
            IReporter reporter = null,
            IWorkloadResolver workloadResolver = null,
            IInstaller workloadInstaller       = null,
            string version = null)
            : base(parseResult)
        {
            _reporter              = reporter ?? Reporter.Output;
            _skipManifestUpdate    = parseResult.ValueForOption <bool>(WorkloadInstallCommandParser.SkipManifestUpdateOption);
            _printDownloadLinkOnly = parseResult.ValueForOption <bool>(WorkloadInstallCommandParser.PrintDownloadLinkOnlyOption);
            _fromCacheOption       = parseResult.ValueForOption <string>(WorkloadInstallCommandParser.FromCacheOption);
            _workloadIds           = parseResult.ValueForArgument <IReadOnlyCollection <string> >(WorkloadInstallCommandParser.WorkloadIdArgument);
            _sdkVersion            = new ReleaseVersion(version ?? Product.Version);

            var dotnetPath = EnvironmentProvider.GetDotnetExeDirectory();
            var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, _sdkVersion.ToString());

            _workloadResolver = workloadResolver ?? WorkloadResolver.Create(workloadManifestProvider, dotnetPath, _sdkVersion.ToString());
            var sdkFeatureBand = new SdkFeatureBand(string.Join('.', _sdkVersion.Major, _sdkVersion.Minor, _sdkVersion.SdkFeatureBand));

            _workloadInstaller = workloadInstaller ?? WorkloadInstallerFactory.GetWorkloadInstaller(_reporter, sdkFeatureBand, _workloadResolver);
        }
示例#28
0
        /// <summary>
        /// Cleans up and removes stale workload packs.
        /// </summary>
        public void GarbageCollectInstalledWorkloadPacks()
        {
            try
            {
                Log?.LogMessage("Starting garbage collection.");
                IEnumerable <SdkFeatureBand> installedFeatureBands = GetInstalledFeatureBands();
                IEnumerable <WorkloadId>     installedWorkloads    = RecordRepository.GetInstalledWorkloads(_sdkFeatureBand);
                IEnumerable <PackInfo>       expectedWorkloadPacks = installedWorkloads
                                                                     .SelectMany(workload => _workloadResolver.GetPacksInWorkload(workload))
                                                                     .Select(pack => _workloadResolver.TryGetPackInfo(pack))
                                                                     .Where(pack => pack != null);
                IEnumerable <WorkloadPackId> expectedPackIds = expectedWorkloadPacks.Select(p => p.Id);

                foreach (PackInfo expectedPack in expectedWorkloadPacks)
                {
                    Log?.LogMessage($"Expected workload pack, ID: {expectedPack.ResolvedPackageId}, version: {expectedPack.Version}.");
                }

                foreach (SdkFeatureBand installedFeatureBand in installedFeatureBands)
                {
                    Log?.LogMessage($"Installed feature band: {installedFeatureBand}");
                }

                IEnumerable <WorkloadPackRecord> installedWorkloadPacks = WorkloadPackRecords.Values.SelectMany(r => r);

                List <WorkloadPackRecord> packsToRemove = new List <WorkloadPackRecord>();

                // We first need to clean up the dependents and then do a pass at removing them. Querying the installed packs
                // is effectively a table scan of the registry to make sure we have accurate information and there's a
                // potential perf hit for both memory and speed when enumerating large sets of registry entries.
                foreach (WorkloadPackRecord packRecord in installedWorkloadPacks)
                {
                    DependencyProvider depProvider = new DependencyProvider(packRecord.ProviderKeyName);

                    // Find all the dependents that look like they belong to SDKs. We only care
                    // about dependents that match the SDK host we're running under. For example, an x86 SDK should not be
                    // modifying the x64 MSI dependents.
                    IEnumerable <string> sdkDependents = depProvider.Dependents
                                                         .Where(d => d.StartsWith($"{DependentPrefix}"))
                                                         .Where(d => d.EndsWith($",{HostArchitecture}"));

                    foreach (string dependent in sdkDependents)
                    {
                        Log?.LogMessage($"Evaluating dependent for workload pack, dependent: {dependent}, pack ID: {packRecord.PackId}, pack version: {packRecord.PackVersion}");

                        // Dependents created by the SDK should have 3 parts, for example, "Microsoft.NET.Sdk,6.0.100,x86".
                        string[] dependentParts = dependent.Split(',');

                        if (dependentParts.Length != 3)
                        {
                            Log?.LogMessage($"Skipping dependent: {dependent}");
                            continue;
                        }

                        try
                        {
                            SdkFeatureBand dependentFeatureBand = new SdkFeatureBand(dependentParts[1]);

                            if (!installedFeatureBands.Contains(dependentFeatureBand))
                            {
                                Log?.LogMessage($"Removing dependent '{dependent}' from provider key '{depProvider.ProviderKeyName}' because its SDK feature band does not match any installed feature bands.");
                                UpdateDependent(InstallRequestType.RemoveDependent, depProvider.ProviderKeyName, dependent);
                            }

                            if (dependentFeatureBand.Equals(_sdkFeatureBand))
                            {
                                // If the current SDK feature band is listed as a dependent, we can validate
                                // the workload pack against the expected pack IDs and versions to potentially remove it.
                                if (!expectedWorkloadPacks.Where(p => packRecord.PackId.Equals(p.ResolvedPackageId))
                                    .Where(p => p.Version.Equals(packRecord.PackVersion.ToString())).Any())
                                {
                                    Log?.LogMessage($"Removing dependent '{dependent}' because the pack record does not match any expected packs.");
                                    UpdateDependent(InstallRequestType.RemoveDependent, depProvider.ProviderKeyName, dependent);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Log?.LogMessage($"{e.Message}");
                            Log?.LogMessage($"{e.StackTrace}");
                            continue;
                        }
                    }

                    // Recheck the registry to see if there are any remaining dependents. If not, we can
                    // remove the workload pack. We'll add it to the list and remove the packs at the end.
                    IEnumerable <string> remainingDependents = depProvider.Dependents;

                    if (remainingDependents.Any())
                    {
                        Log?.LogMessage($"{packRecord.PackId} ({packRecord.PackVersion}) will not be removed because other dependents remain: {string.Join(", ", remainingDependents)}.");
                    }
                    else
                    {
                        packsToRemove.Add(packRecord);
                    }
                }

                foreach (WorkloadPackRecord record in packsToRemove)
                {
                    // We need to make sure the product is actually installed and that we're not dealing with an orphaned record, e.g.
                    // if a previous removal was interrupted. We can't safely clean up orphaned records because it's too expensive
                    // to query all installed components and determine the product codes associated with the component that
                    // created the record.
                    DetectState state = Detect(record.ProductCode, out string _);

                    if (state == DetectState.Present)
                    {
                        // We don't have package information and can't construct it accurately.
                        string id = $"{record.PackId}.Msi.{HostArchitecture}";

                        MsiPayload msiPayload = GetCachedMsiPayload(id, record.PackVersion.ToString());
                        VerifyPackage(msiPayload);
                        InstallAction plannedAction = GetPlannedAction(state, InstallAction.Uninstall);

                        string logFile = GetMsiLogName(record, plannedAction);

                        uint error = ExecuteWithProgress($"Removing {id} ", () => UninstallMsi(record.ProductCode, logFile));
                        ExitOnError(error, $"Failed to uninstall {msiPayload.MsiPath}.");
                    }
                }
            }
            catch (Exception e)
            {
                LogException(e);
                throw;
            }
        }
示例#29
0
 public void RollBackWorkloadPackInstall(PackInfo packInfo, SdkFeatureBand sdkFeatureBand)
 {
     Log?.LogMessage($"Rolling back workload pack.");
     LogPackInfo(packInfo);
 }
示例#30
0
        public void InstallWorkloadManifest(ManifestId manifestId, ManifestVersion manifestVersion, SdkFeatureBand sdkFeatureBand, DirectoryPath?offlineCache = null)
        {
            try
            {
                Log?.LogMessage($"Installing manifest, {nameof(manifestId)}: {manifestId}, {nameof(manifestVersion)}: {manifestVersion}, {nameof(sdkFeatureBand)}: {sdkFeatureBand}");

                // Resolve the package ID for the manifest payload package
                string msiPackageId      = WorkloadManifestUpdater.GetManifestPackageId(sdkFeatureBand, manifestId).ToString();
                string msiPackageVersion = $"{manifestVersion}";

                Log?.LogMessage($"Resolving {manifestId} ({manifestVersion}) to {msiPackageId}.{msiPackageVersion}.");

                // Retrieve the payload from the MSI package cache.
                MsiPayload msiPayload = GetCachedMsiPayload(msiPackageId, msiPackageVersion);
                VerifyPackage(msiPayload);
            }
            catch (Exception e)
            {
                LogException(e);
                throw;
            }
        }