/// <summary>
        /// Installs function app dependencies.
        /// </summary>
        internal Exception InstallFunctionAppDependencies(PowerShell firstPwsh, Func <PowerShell> pwshFactory, ILogger logger)
        {
            var isBackgroundInstallation = false;

            try
            {
                if (AreAcceptableDependenciesAlreadyInstalled())
                {
                    isBackgroundInstallation = true;

                    _nextSnapshotPath = _storage.CreateNewSnapshotPath();

                    // Purge before installing a new snapshot, as we may be able to free some space.
                    _purger.Purge(logger);

                    if (!IsAnyInstallationStartedRecently())
                    {
                        logger.Log(
                            isUserOnlyLog: false,
                            LogLevel.Trace,
                            PowerShellWorkerStrings.AcceptableFunctionAppDependenciesAlreadyInstalled);

                        // Background installation: can't use the firstPwsh runspace because it belongs
                        // to the pool used to run functions code, so create a new runspace.
                        using (var pwsh = pwshFactory())
                        {
                            _installer.InstallSnapshot(_dependenciesFromManifest, _nextSnapshotPath, pwsh, logger);
                        }

                        // Now that a new snapshot has been installed, there is a chance an old snapshot can be purged.
                        _purger.Purge(logger);
                    }
                }
                else
                {
                    // Foreground installation: *may* use the firstPwsh runspace, since the function execution is
                    // blocked until the installation is complete, so we are potentially saving some time by reusing
                    // the runspace as opposed to creating another one.
                    _installer.InstallSnapshot(_dependenciesFromManifest, _currentSnapshotPath, firstPwsh, logger);
                }
            }
            catch (Exception e)
            {
                var errorMsg = string.Format(PowerShellWorkerStrings.FailToInstallFuncAppDependencies, e.Message);
                _dependencyInstallationError = new DependencyInstallationException(errorMsg, e);

                if (isBackgroundInstallation)
                {
                    var dependenciesNotUpdatedMessage =
                        string.Format(PowerShellWorkerStrings.DependenciesUpgradeSkippedMessage, _dependencyInstallationError.Message);

                    logger.Log(isUserOnlyLog: false, LogLevel.Warning, dependenciesNotUpdatedMessage, _dependencyInstallationError);
                }
            }

            return(_dependencyInstallationError);
        }
Beispiel #2
0
        /// <summary>
        /// Returns the path for the new dependencies snapshot.
        /// </summary>
        public string InstallAndPurgeSnapshots(Func <PowerShell> pwshFactory, ILogger logger)
        {
            try
            {
                // Purge before installing a new snapshot, as we may be able to free some space.
                _purger.Purge(logger);

                if (IsAnyInstallationStartedRecently())
                {
                    return(null);
                }

                var nextSnapshotPath = _storage.CreateNewSnapshotPath();

                using (var pwsh = pwshFactory())
                {
                    _installer.InstallSnapshot(
                        _dependencyManifest,
                        nextSnapshotPath,
                        pwsh,
                        // Background dependency upgrades are optional because the current
                        // worker already has a good enough snapshot, and nothing depends on
                        // the new snapshot yet, so installation failures will not affect
                        // function invocations.
                        DependencySnapshotInstallationMode.Optional,
                        logger);
                }

                // Now that a new snapshot has been installed, there is a chance an old snapshot can be purged.
                _purger.Purge(logger);

                return(nextSnapshotPath);
            }
            catch (Exception e)
            {
                logger.Log(
                    isUserOnlyLog: false,
                    RpcLog.Types.Level.Warning,
                    string.Format(PowerShellWorkerStrings.DependenciesUpgradeSkippedMessage, e.Message));

                return(null);
            }
        }