private void UpdateWorkloadsWithInstallRecord( IEnumerable <WorkloadId> workloadIds, SdkFeatureBand sdkFeatureBand, IEnumerable <ManifestVersionUpdate> manifestsToUpdate, DirectoryPath?offlineCache = null) { if (_workloadInstaller.GetInstallationUnit().Equals(InstallationUnit.Packs)) { var installer = _workloadInstaller.GetPackInstaller(); IEnumerable <PackInfo> workloadPackToUpdate = new List <PackInfo>(); var transaction = new CliTransaction(); transaction.RollbackStarted = () => { Reporter.WriteLine(LocalizableStrings.RollingBackInstall); }; // Don't hide the original error if roll back fails, but do log the rollback failure transaction.RollbackFailed = ex => { Reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, ex.Message)); }; transaction.Run( action: context => { bool rollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); foreach (var manifestUpdate in manifestsToUpdate) { _workloadInstaller.InstallWorkloadManifest(manifestUpdate, context, offlineCache, rollback); } _workloadResolver.RefreshWorkloadManifests(); workloadPackToUpdate = GetUpdatablePacks(installer); installer.InstallWorkloadPacks(workloadPackToUpdate, sdkFeatureBand, context, offlineCache); }, rollback: () => { // Nothing to roll back at this level, InstallWorkloadManifest and InstallWorkloadPacks handle the transaction rollback }); } else { var installer = _workloadInstaller.GetWorkloadInstaller(); foreach (var workloadId in workloadIds) { installer.InstallWorkload(workloadId); } } }
public void GivenManagedInstallItCanRollBackInstallFailures() { var version = "6.0.100"; var(dotnetRoot, installer, nugetInstaller) = GetTestInstaller(failingInstaller: true); var packInfo = CreatePackInfo("Xamarin.Android.Sdk", "8.4.7", WorkloadPackKind.Sdk, Path.Combine(dotnetRoot, "packs", "Xamarin.Android.Sdk", "8.4.7"), "Xamarin.Android.Sdk"); var exceptionThrown = Assert.Throws <Exception>(() => { var transaction = new CliTransaction(); transaction.Run(context => installer.InstallWorkloadPacks(new[] { packInfo }, new SdkFeatureBand(version), context)); }); exceptionThrown.Message.Should().Be("Test Failure"); var failingNugetInstaller = nugetInstaller as FailingNuGetPackageDownloader; // Nupkgs should be removed Directory.GetFiles(failingNugetInstaller.MockPackageDir).Should().BeEmpty(); // Packs should be removed Directory.Exists(packInfo.Path).Should().BeFalse(); }
private void InstallWorkloadsWithInstallRecord( IEnumerable <WorkloadId> workloadIds, SdkFeatureBand sdkFeatureBand, IEnumerable <ManifestVersionUpdate> manifestsToUpdate, DirectoryPath?offlineCache) { if (_workloadInstaller.GetInstallationUnit().Equals(InstallationUnit.Packs)) { var installer = _workloadInstaller.GetPackInstaller(); IEnumerable <PackInfo> workloadPackToInstall = new List <PackInfo>(); IEnumerable <WorkloadId> newWorkloadInstallRecords = new List <WorkloadId>(); var transaction = new CliTransaction(); transaction.RollbackStarted = () => { Reporter.WriteLine(LocalizableStrings.RollingBackInstall); }; // Don't hide the original error if roll back fails, but do log the rollback failure transaction.RollbackFailed = ex => { Reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, ex.Message)); }; transaction.Run( action: context => { bool rollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); foreach (var manifestUpdate in manifestsToUpdate) { _workloadInstaller.InstallWorkloadManifest(manifestUpdate, context, offlineCache, rollback); } _workloadResolver.RefreshWorkloadManifests(); workloadPackToInstall = GetPacksToInstall(workloadIds); installer.InstallWorkloadPacks(workloadPackToInstall, sdkFeatureBand, context, offlineCache); var recordRepo = _workloadInstaller.GetWorkloadInstallationRecordRepository(); newWorkloadInstallRecords = workloadIds.Except(recordRepo.GetInstalledWorkloads(sdkFeatureBand)); foreach (var workloadId in newWorkloadInstallRecords) { recordRepo.WriteWorkloadInstallationRecord(workloadId, sdkFeatureBand); } }, rollback: () => { // InstallWorkloadManifest and InstallWorkloadPacks already handle rolling back their actions, so here we only // need to delete the installation records foreach (var workloadId in newWorkloadInstallRecords) { _workloadInstaller.GetWorkloadInstallationRecordRepository() .DeleteWorkloadInstallationRecord(workloadId, sdkFeatureBand); } }); } else { var installer = _workloadInstaller.GetWorkloadInstaller(); foreach (var workloadId in workloadIds) { installer.InstallWorkload(workloadId); } } }