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))); }
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); }
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)); }
/// <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); }
public WorkloadManifestUpdater( IReporter reporter, IWorkloadManifestProvider workloadManifestProvider, INuGetPackageDownloader nugetPackageDownloader, string userHome) { _reporter = reporter; _workloadManifestProvider = workloadManifestProvider; _userHome = userHome; _nugetPackageDownloader = nugetPackageDownloader; _sdkFeatureBand = new SdkFeatureBand(_workloadManifestProvider.GetSdkFeatureBand()); }
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(); }
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)))); }
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; }
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; }
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; }
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); }
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)); }
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; } }
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); }
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); })); }
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; }
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; }
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)); }
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); } }
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); } } } }
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(); }
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 } }
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; } }
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); }
/// <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; } }
public void RollBackWorkloadPackInstall(PackInfo packInfo, SdkFeatureBand sdkFeatureBand) { Log?.LogMessage($"Rolling back workload pack."); LogPackInfo(packInfo); }
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; } }