// This method calls iterates through repositories (by priority order) to search for the pkgs to install public void ProcessRepositories(string[] packageNames, string[] repository, bool trustRepository, PSCredential credential) { var listOfRepositories = RepositorySettings.Read(repository, out string[] _); List <string> packagesToInstall = packageNames.ToList(); var yesToAll = false; var noToAll = false; var repositoryIsNotTrusted = "Untrusted repository"; var queryInstallUntrustedPackage = "You are installing the modules from an untrusted repository. If you trust this repository, change its Trusted value by running the Set-PSResourceRepository cmdlet. Are you sure you want to install the PSresource from '{0}' ?"; foreach (var repo in listOfRepositories) { // If no more packages to install, then return if (!packagesToInstall.Any()) { return; } var sourceTrusted = false; string repoName = repo.Name; _cmdletPassedIn.WriteDebug(string.Format("Attempting to search for packages in '{0}'", repoName)); // Source is only trusted if it's set at the repository level to be trusted, -TrustRepository flag is true, -Force flag is true // OR the user issues trust interactively via console. if (repo.Trusted == false && !trustRepository && !_force) { _cmdletPassedIn.WriteDebug("Checking if untrusted repository should be used"); if (!(yesToAll || noToAll)) { // Prompt for installation of package from untrusted repository var message = string.Format(CultureInfo.InvariantCulture, queryInstallUntrustedPackage, repoName); sourceTrusted = _cmdletPassedIn.ShouldContinue(message, repositoryIsNotTrusted, true, ref yesToAll, ref noToAll); } } else { sourceTrusted = true; } if (sourceTrusted || yesToAll) { _cmdletPassedIn.WriteDebug("Untrusted repository accepted as trusted source."); // If it can't find the pkg in one repository, it'll look for it in the next repo in the list var isLocalRepo = repo.Url.AbsoluteUri.StartsWith(Uri.UriSchemeFile + Uri.SchemeDelimiter, StringComparison.OrdinalIgnoreCase); var findHelper = new FindHelper(_cancellationToken, _cmdletPassedIn); // Finds parent packages and dependencies IEnumerable <PSResourceInfo> pkgsFromRepoToInstall = findHelper.FindByResourceName( name: packageNames, type: ResourceType.None, version: _versionRange != null ? _versionRange.OriginalString : null, prerelease: _prerelease, tag: null, repository: new string[] { repoName }, credential: credential, includeDependencies: true); foreach (PSResourceInfo a in pkgsFromRepoToInstall) { var test = a; _cmdletPassedIn.WriteVerbose(a.Version.ToString()); } // Select the first package from each name group, which is guaranteed to be the latest version. // We should only have one version returned for each package name // e.g.: // PackageA (version 1.0) // PackageB (version 2.0) // PackageC (version 1.0) pkgsFromRepoToInstall = pkgsFromRepoToInstall.GroupBy( m => new { m.Name }).Select( group => group.First()).ToList(); if (!pkgsFromRepoToInstall.Any()) { _cmdletPassedIn.WriteVerbose(string.Format("None of the specified resources were found in the '{0}' repository.", repoName)); // Check in the next repository continue; } // Check to see if the pkgs (including dependencies) are already installed (ie the pkg is installed and the version satisfies the version range provided via param) if (!_reinstall) { // Removes all of the names that are already installed from the list of names to search for pkgsFromRepoToInstall = FilterByInstalledPkgs(pkgsFromRepoToInstall); } if (!pkgsFromRepoToInstall.Any()) { continue; } List <string> pkgsInstalled = InstallPackage(pkgsFromRepoToInstall, repoName, repo.Url.AbsoluteUri, credential, isLocalRepo); foreach (string name in pkgsInstalled) { packagesToInstall.Remove(name); } } } }
// This method calls iterates through repositories (by priority order) to search for the pkgs to install private List <PSResourceInfo> ProcessRepositories( string[] repository, bool trustRepository, PSCredential credential, bool skipDependencyCheck) { var listOfRepositories = RepositorySettings.Read(repository, out string[] _); var yesToAll = false; var noToAll = false; var findHelper = new FindHelper(_cancellationToken, _cmdletPassedIn); List <PSResourceInfo> allPkgsInstalled = new List <PSResourceInfo>(); foreach (var repo in listOfRepositories) { // If no more packages to install, then return if (!_pkgNamesToInstall.Any()) { return(allPkgsInstalled); } string repoName = repo.Name; _cmdletPassedIn.WriteVerbose(string.Format("Attempting to search for packages in '{0}'", repoName)); // Source is only trusted if it's set at the repository level to be trusted, -TrustRepository flag is true, -Force flag is true // OR the user issues trust interactively via console. var sourceTrusted = true; if (repo.Trusted == false && !trustRepository && !_force) { _cmdletPassedIn.WriteVerbose("Checking if untrusted repository should be used"); if (!(yesToAll || noToAll)) { // Prompt for installation of package from untrusted repository var message = string.Format(CultureInfo.InvariantCulture, MsgInstallUntrustedPackage, repoName); sourceTrusted = _cmdletPassedIn.ShouldContinue(message, MsgRepositoryNotTrusted, true, ref yesToAll, ref noToAll); } } if (!sourceTrusted && !yesToAll) { continue; } _cmdletPassedIn.WriteVerbose("Untrusted repository accepted as trusted source."); // If it can't find the pkg in one repository, it'll look for it in the next repo in the list var isLocalRepo = repo.Url.AbsoluteUri.StartsWith(Uri.UriSchemeFile + Uri.SchemeDelimiter, StringComparison.OrdinalIgnoreCase); // Finds parent packages and dependencies IEnumerable <PSResourceInfo> pkgsFromRepoToInstall = findHelper.FindByResourceName( name: _pkgNamesToInstall.ToArray(), type: ResourceType.None, version: _versionRange != null ? _versionRange.OriginalString : null, prerelease: _prerelease, tag: null, repository: new string[] { repoName }, credential: credential, includeDependencies: !skipDependencyCheck); if (!pkgsFromRepoToInstall.Any()) { _cmdletPassedIn.WriteVerbose(string.Format("None of the specified resources were found in the '{0}' repository.", repoName)); // Check in the next repository continue; } // Select the first package from each name group, which is guaranteed to be the latest version. // We should only have one version returned for each package name // e.g.: // PackageA (version 1.0) // PackageB (version 2.0) // PackageC (version 1.0) pkgsFromRepoToInstall = pkgsFromRepoToInstall.GroupBy( m => new { m.Name }).Select( group => group.First()).ToList(); // Check to see if the pkgs (including dependencies) are already installed (ie the pkg is installed and the version satisfies the version range provided via param) if (!_reinstall) { pkgsFromRepoToInstall = FilterByInstalledPkgs(pkgsFromRepoToInstall); } if (!pkgsFromRepoToInstall.Any()) { continue; } List <PSResourceInfo> pkgsInstalled = InstallPackage( pkgsFromRepoToInstall, repo.Url.AbsoluteUri, credential, isLocalRepo); foreach (PSResourceInfo pkg in pkgsInstalled) { _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); } allPkgsInstalled.AddRange(pkgsInstalled); } // At this only package names left were those which could not be found in registered repositories foreach (string pkgName in _pkgNamesToInstall) { var message = String.Format("Package '{0}' with requested version range {1} could not be installed as it was not found in any registered repositories", pkgName, _versionRange.ToString()); var ex = new ArgumentException(message); var ResourceNotFoundError = new ErrorRecord(ex, "ResourceNotFoundError", ErrorCategory.ObjectNotFound, null); _cmdletPassedIn.WriteError(ResourceNotFoundError); } return(allPkgsInstalled); }
internal static void CollectJobs(PSCmdlet invokeAll, ConcurrentDictionary <int, Job> jobs, int totalJobs, string progressBarStage, bool force, bool returnAsJobObject, bool appendJobNameToResult, int jobID = 0, bool noFileLogging = false, bool quiet = false) { if (!force && jobID == 1) { LogHelper.LogProgress("Waiting 30 seconds for the first job to complete", invokeAll, "Error Check", quiet: quiet); //For the first job, default the wait to 30 sceonds and do a error check, if it is not completed, prompt user with option to wait or to continue.. if ((bool)jobs.First().Value.JobTask.Wait(TimeSpan.FromSeconds(30))) { LogHelper.Log(fileVerboseLogTypes, "First Job completed", invokeAll, noFileLogging); Job firstCollectedJob = CollectJob(invokeAll, jobs.First().Value, returnAsJobObject, force, appendJobNameToResult); if (!jobs.TryRemove(firstCollectedJob.ID, out Job removedJob) == true) { LogHelper.LogDebug(string.Format("Unable to remove Job {0}", firstCollectedJob.ID), invokeAll); } LogHelper.Log(fileVerboseLogTypes, "Will queue rest of the Jobs as the current Batch completes", invokeAll, noFileLogging); return; } else { LogHelper.Log(fileVerboseLogTypes, "First Job didn't complete in 30 seconds", invokeAll, noFileLogging); if (!invokeAll.ShouldContinue("First instance still running, Want to continue queuing the rest of the jobs?", "FirstJob Error Check")) { throw new Exception("Aborted from the first instance error check"); } } LogHelper.LogProgress("Completed", invokeAll, "Error Check", 100, quiet: quiet); } var pendingJobs = jobs.Where(q => q.Value.IsCollected != true); var faultedJobs = jobs.Where(f => f.Value.IsFaulted == true || f.Value.PowerShell.HadErrors == true); if (pendingJobs.Count() <= 0) { LogHelper.Log(fileVerboseLogTypes, "There are no pending jobs to collect", invokeAll, noFileLogging); return; } int completedJobs = totalJobs - pendingJobs.Count(); LogHelper.LogProgress(string.Format("Active Queue: {0} / Completed: {1} - Faulted {2}, waiting for any one of them to complete", pendingJobs.Count(), completedJobs, faultedJobs.Count()), invokeAll, progressBarStage, quiet: quiet); //Todo: log something to the file, but not every job completed int completedTask = Task.WaitAny((from pendingJob in pendingJobs select pendingJob.Value.JobTask).ToArray()); if (jobs.TryGetValue(pendingJobs.ElementAt(completedTask).Value.ID, out Job processedJob) == true) { Job collectedJob = CollectJob(invokeAll, processedJob, returnAsJobObject, force, appendJobNameToResult); if (!jobs.TryRemove(collectedJob.ID, out Job removedJob) == true) { LogHelper.LogDebug(string.Format("Unable to remove Job {0}", collectedJob.ID), invokeAll); } } else { LogHelper.Log(fileErrorLogTypes, string.Format("TaskID {0} completed, but wasnt found at Jobs array. Please report this issue", completedTask), invokeAll, noFileLogging); } }