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));
            }
        }
Exemple #2
0
        public IToolPackage InstallPackage(
            string packageId,
            string packageVersion  = null,
            string targetFramework = null,
            FilePath?nugetConfig   = null,
            string source          = null,
            string verbosity       = null)
        {
            if (packageId == null)
            {
                throw new ArgumentNullException(nameof(packageId));
            }

            var    packageRootDirectory = _store.Root.WithSubDirectories(packageId);
            string rollbackDirectory    = null;

            return(TransactionalAction.Run <IToolPackage>(
                       action: () => {
                try
                {
                    var stageDirectory = _store.Root.WithSubDirectories(StagingDirectory, Path.GetRandomFileName());
                    Directory.CreateDirectory(stageDirectory.Value);
                    rollbackDirectory = stageDirectory.Value;

                    var tempProject = CreateTempProject(
                        packageId: packageId,
                        packageVersion: packageVersion,
                        targetFramework: targetFramework ?? BundledTargetFramework.GetTargetFrameworkMoniker(),
                        restoreDirectory: stageDirectory);

                    try
                    {
                        _projectRestorer.Restore(
                            tempProject,
                            stageDirectory,
                            nugetConfig,
                            source,
                            verbosity);
                    }
                    finally
                    {
                        File.Delete(tempProject.Value);
                    }

                    packageVersion = Path.GetFileName(
                        Directory.EnumerateDirectories(
                            stageDirectory.WithSubDirectories(packageId).Value).Single());

                    var packageDirectory = packageRootDirectory.WithSubDirectories(packageVersion);
                    if (Directory.Exists(packageDirectory.Value))
                    {
                        throw new ToolPackageException(
                            string.Format(
                                CommonLocalizableStrings.ToolPackageConflictPackageId,
                                packageId,
                                packageVersion));
                    }

                    Directory.CreateDirectory(packageRootDirectory.Value);
                    Directory.Move(stageDirectory.Value, packageDirectory.Value);
                    rollbackDirectory = packageDirectory.Value;

                    return new ToolPackageInstance(
                        _store,
                        packageId,
                        packageVersion,
                        packageDirectory);
                }
                catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException)
                {
                    throw new ToolPackageException(
                        string.Format(
                            CommonLocalizableStrings.FailedToInstallToolPackage,
                            packageId,
                            ex.Message),
                        ex);
                }
            },
                       rollback: () => {
                if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory))
                {
                    Directory.Delete(rollbackDirectory, true);
                }

                // Delete the root if it is empty
                if (Directory.Exists(packageRootDirectory.Value) &&
                    !Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any())
                {
                    Directory.Delete(packageRootDirectory.Value, false);
                }
            }));
        }
Exemple #3
0
        public IToolPackage InstallPackage(PackageId packageId,
                                           VersionRange versionRange         = null,
                                           string targetFramework            = null,
                                           FilePath?nugetConfig              = null,
                                           DirectoryPath?rootConfigDirectory = null,
                                           string[] additionalFeeds          = null,
                                           string verbosity = null)
        {
            var    packageRootDirectory = _store.GetRootPackageDirectory(packageId);
            string rollbackDirectory    = null;

            return(TransactionalAction.Run <IToolPackage>(
                       action: () => {
                try
                {
                    var stageDirectory = _store.GetRandomStagingDirectory();
                    Directory.CreateDirectory(stageDirectory.Value);
                    rollbackDirectory = stageDirectory.Value;

                    var tempProject = CreateTempProject(
                        packageId: packageId,
                        versionRange: versionRange,
                        targetFramework: targetFramework ?? BundledTargetFramework.GetTargetFrameworkMoniker(),
                        restoreDirectory: stageDirectory,
                        assetJsonOutputDirectory: stageDirectory,
                        rootConfigDirectory: rootConfigDirectory,
                        additionalFeeds: additionalFeeds);

                    try
                    {
                        _projectRestorer.Restore(
                            tempProject,
                            nugetConfig,
                            verbosity: verbosity);
                    }
                    finally
                    {
                        File.Delete(tempProject.Value);
                    }

                    var version = _store.GetStagedPackageVersion(stageDirectory, packageId);
                    var packageDirectory = _store.GetPackageDirectory(packageId, version);
                    if (Directory.Exists(packageDirectory.Value))
                    {
                        throw new ToolPackageException(
                            string.Format(
                                CommonLocalizableStrings.ToolPackageConflictPackageId,
                                packageId,
                                version.ToNormalizedString()));
                    }

                    Directory.CreateDirectory(packageRootDirectory.Value);
                    FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(stageDirectory.Value, packageDirectory.Value));
                    rollbackDirectory = packageDirectory.Value;

                    return new ToolPackageInstance(_store, packageId, version, packageDirectory);
                }
                catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException)
                {
                    throw new ToolPackageException(
                        string.Format(
                            CommonLocalizableStrings.FailedToInstallToolPackage,
                            packageId,
                            ex.Message),
                        ex);
                }
            },
                       rollback: () => {
                if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory))
                {
                    Directory.Delete(rollbackDirectory, true);
                }

                // Delete the root if it is empty
                if (Directory.Exists(packageRootDirectory.Value) &&
                    !Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any())
                {
                    Directory.Delete(packageRootDirectory.Value, false);
                }
            }));
        }
Exemple #4
0
        public IToolPackage InstallPackage(PackageId packageId,
                                           VersionRange versionRange         = null,
                                           string targetFramework            = null,
                                           FilePath?nugetConfig              = null,
                                           DirectoryPath?rootConfigDirectory = null,
                                           string[] additionalFeeds          = null,
                                           string verbosity = null)
        {
            var    packageRootDirectory = _store.GetRootPackageDirectory(packageId);
            string rollbackDirectory    = null;

            return(TransactionalAction.Run <IToolPackage>(
                       action: () => {
                var stageDirectory = _store.GetRandomStagingDirectory();
                _fileSystem.Directory.CreateDirectory(stageDirectory.Value);
                rollbackDirectory = stageDirectory.Value;

                var tempProject = new FilePath(Path.Combine(stageDirectory.Value, ProjectFileName));

                // Write a fake project with the requested package id, version, and framework
                _fileSystem.File.WriteAllText(
                    tempProject.Value,
                    $"{packageId}:{versionRange?.ToString("S", new VersionRangeFormatter()) ?? "*"}:{targetFramework}");

                // Perform a restore on the fake project
                _projectRestorer.Restore(
                    tempProject,
                    stageDirectory,
                    nugetConfig,
                    verbosity);

                if (_installCallback != null)
                {
                    _installCallback();
                }

                var version = _store.GetStagedPackageVersion(stageDirectory, packageId);
                var packageDirectory = _store.GetPackageDirectory(packageId, version);
                if (_fileSystem.Directory.Exists(packageDirectory.Value))
                {
                    throw new ToolPackageException(
                        string.Format(
                            CommonLocalizableStrings.ToolPackageConflictPackageId,
                            packageId,
                            version.ToNormalizedString()));
                }

                _fileSystem.Directory.CreateDirectory(packageRootDirectory.Value);
                _fileSystem.Directory.Move(stageDirectory.Value, packageDirectory.Value);
                rollbackDirectory = packageDirectory.Value;

                IEnumerable <string> warnings = null;
                _warningsMap.TryGetValue(packageId, out warnings);

                IReadOnlyList <FilePath> packedShims = null;
                _packagedShimsMap.TryGetValue(packageId, out packedShims);

                return new ToolPackageMock(_fileSystem, packageId, version, packageDirectory, warnings: warnings, packagedShims: packedShims);
            },
                       rollback: () => {
                if (rollbackDirectory != null && _fileSystem.Directory.Exists(rollbackDirectory))
                {
                    _fileSystem.Directory.Delete(rollbackDirectory, true);
                }
                if (_fileSystem.Directory.Exists(packageRootDirectory.Value) &&
                    !_fileSystem.Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any())
                {
                    _fileSystem.Directory.Delete(packageRootDirectory.Value, false);
                }
            }));
        }
Exemple #5
0
        public void InstallWorkloadPack(PackInfo packInfo, SdkFeatureBand sdkFeatureBand, DirectoryPath?offlineCache = null)
        {
            _reporter.WriteLine(string.Format(LocalizableStrings.InstallingPackVersionMessage, packInfo.Id, packInfo.Version));
            var tempDirsToDelete  = new List <string>();
            var tempFilesToDelete = new List <string>();

            try
            {
                TransactionalAction.Run(
                    action: () =>
                {
                    if (!PackIsInstalled(packInfo))
                    {
                        string packagePath;
                        if (offlineCache == null || !offlineCache.HasValue)
                        {
                            packagePath = _nugetPackageDownloader.DownloadPackageAsync(new PackageId(packInfo.ResolvedPackageId), new NuGetVersion(packInfo.Version), _packageSourceLocation).Result;
                            tempFilesToDelete.Add(packagePath);
                        }
                        else
                        {
                            _reporter.WriteLine(string.Format(LocalizableStrings.UsingCacheForPackInstall, packInfo.Id, packInfo.Version, offlineCache));
                            packagePath = Path.Combine(offlineCache.Value.Value, $"{packInfo.ResolvedPackageId}.{packInfo.Version}.nupkg");
                            if (!File.Exists(packagePath))
                            {
                                throw new Exception(string.Format(LocalizableStrings.CacheMissingPackage, packInfo.ResolvedPackageId, packInfo.Version, offlineCache));
                            }
                        }

                        if (!Directory.Exists(Path.GetDirectoryName(packInfo.Path)))
                        {
                            Directory.CreateDirectory(Path.GetDirectoryName(packInfo.Path));
                        }

                        if (IsSingleFilePack(packInfo))
                        {
                            File.Copy(packagePath, packInfo.Path);
                        }
                        else
                        {
                            var tempExtractionDir = Path.Combine(_tempPackagesDir.Value, $"{packInfo.Id}-{packInfo.Version}-extracted");
                            tempDirsToDelete.Add(tempExtractionDir);
                            Directory.CreateDirectory(tempExtractionDir);
                            var packFiles = _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempExtractionDir)).Result;

                            FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(tempExtractionDir, packInfo.Path));
                        }
                    }
                    else
                    {
                        _reporter.WriteLine(string.Format(LocalizableStrings.WorkloadPackAlreadyInstalledMessage, packInfo.Id, packInfo.Version));
                    }

                    WritePackInstallationRecord(packInfo, sdkFeatureBand);
                },
                    rollback: () => {
                    try
                    {
                        _reporter.WriteLine(string.Format(LocalizableStrings.RollingBackPackInstall, packInfo.Id));
                        RollBackWorkloadPackInstall(packInfo, sdkFeatureBand);
                    }
                    catch (Exception e)
                    {
                        // Don't hide the original error if roll back fails
                        _reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, e.Message));
                    }
                });
            }
            finally
            {
                // Delete leftover dirs and files
                foreach (var file in tempFilesToDelete)
                {
                    if (File.Exists(file))
                    {
                        File.Delete(file);
                    }
                }
                foreach (var dir in tempDirsToDelete)
                {
                    if (Directory.Exists(dir))
                    {
                        Directory.Delete(dir, true);
                    }
                }
            }
        }