コード例 #1
0
        public DeploymentSettingsPrioritiesTests()
        {
            var settingsPriority1 = new Dictionary <string, string>();

            settingsPriority1["key1"] = "settingsPriority1_value1";
            settingsPriority1["key2"] = "settingsPriority1_value2";
            settingsPriority1["key3"] = "settingsPriority1_value3";
            settingsPriority1["key4"] = "settingsPriority1_value4";

            var settingsPriority2 = new Dictionary <string, string>();

            settingsPriority1["key2"] = "settingsPriority2_value2";
            settingsPriority1["key3"] = "settingsPriority2_value3";
            settingsPriority1["key5"] = "settingsPriority2_value5";
            settingsPriority1["key6"] = "settingsPriority2_value6";

            var settingsPriority50 = new Dictionary <string, string>();

            settingsPriority1["key1"] = "settingsPriority50_value1";
            settingsPriority1["key2"] = "settingsPriority50_value2";
            settingsPriority1["key5"] = "settingsPriority50_value5";
            settingsPriority1["key7"] = "settingsPriority50_value7";

            var testProvider1     = new BasicSettingsProvider(settingsPriority1, (SettingsProvidersPriority)1);
            var testProvider2     = new BasicSettingsProvider(settingsPriority2, (SettingsProvidersPriority)2);
            var testProvider50    = new BasicSettingsProvider(settingsPriority50, (SettingsProvidersPriority)50);
            var settingsProviders = new ISettingsProvider[] { testProvider1, testProvider50, testProvider2 };

            PerSiteSettingsProvider perSiteSettings = null;

            deploymentSettingsManager = new DeploymentSettingsManager(perSiteSettings, settingsProviders);
        }
コード例 #2
0
        /// <summary>
        /// Ensures valid /home/site/deployments/settings.xml is loaded, deletes
        /// corrupt settings.xml file
        /// </summary>
        /// <param name="environment">
        /// IEnvironment object that maintains paths used by kudu
        /// </param>
        internal static void EnsureValidDeploymentXmlSettings(IEnvironment environment)
        {
            var path = GetSettingsPath(environment);

            if (!FileSystemHelpers.FileExists(path))
            {
                return;
            }
            try
            {
                var settings = new DeploymentSettingsManager(new XmlSettings.Settings(path));
                settings.GetValue(SettingsKeys.TraceLevel);
            }
            catch (Exception ex)
            {
                DateTime lastWriteTimeUtc = DateTime.MinValue;
                OperationManager.SafeExecute(() => lastWriteTimeUtc = File.GetLastWriteTimeUtc(path));
                // trace initialization error
                KuduEventSource.Log.KuduException(
                    ServerConfiguration.GetApplicationName(),
                    "Startup.cs",
                    string.Empty,
                    string.Empty,
                    string.Format("Invalid '{0}' is detected and deleted.  Last updated time was {1}.", path,
                                  lastWriteTimeUtc),
                    ex.ToString());
                File.Delete(path);
            }
        }
コード例 #3
0
        public void AllowShallowClonesReturnsFalseForNonTrueLikeValues(string value)
        {
            // Arrange
            var settings = new Mock <ISettings>(MockBehavior.Strict);

            settings.Setup(s => s.GetValue("deployment", "SCM_USE_SHALLOW_CLONE")).Returns(value);
            var deploymentSettings = new DeploymentSettingsManager(settings.Object, DefaultSettingsProvider);

            // Act
            bool result = deploymentSettings.AllowShallowClones();

            // Assert
            Assert.False(result);
        }
コード例 #4
0
        public void GetBranchUsesPersistedBranchValueIfAvailable()
        {
            // Arrange
            var settings = new Mock <ISettings>();

            settings.Setup(s => s.GetValue("deployment", "branch")).Returns("my-branch");
            var deploymentSettings = new DeploymentSettingsManager(settings.Object, DefaultSettingsProvider);

            // Act
            string branch = deploymentSettings.GetBranch();

            // Assert
            Assert.Equal("my-branch", branch);
        }
コード例 #5
0
        public void SetBranchClearsLegacyKeyIfPresent()
        {
            // Arrange
            var settings = new Mock <ISettings>(MockBehavior.Strict);

            settings.Setup(s => s.DeleteValue("deployment", "branch")).Returns(true).Verifiable();
            settings.Setup(s => s.SetValue("deployment", "deployment_branch", "my-branch")).Verifiable();
            var deploymentSettings = new DeploymentSettingsManager(settings.Object, DefaultSettingsProvider);

            // Act
            deploymentSettings.SetBranch("my-branch");

            // Assert
            settings.Verify();
        }
コード例 #6
0
        public void GetBranchDoesNotUnifyValuesWithLegacyKey()
        {
            // Arrange
            var settings        = Mock.Of <ISettings>();
            var defaultSettings = new Dictionary <string, string>
            {
                { "deployment_branch", "my-deployment-branch" },
                { "branch", "my-legacy-branch" }
            };
            var deploymentSettings = new DeploymentSettingsManager(settings, BuildSettingsProviders(defaultSettings));

            // Act
            string branch = deploymentSettings.GetBranch();

            // Assert
            Assert.Equal("my-deployment-branch", branch);
        }
コード例 #7
0
        public void GetBranchUsesLegacyBranchValueIfDeploymentBranchIsOnlyAvailableAsPartOfEnvironment()
        {
            // Arrange
            var settings        = new Mock <ISettings>();
            var defaultSettings = new Dictionary <string, string>
            {
                { "deployment_branch", "my-deployment-branch" }
            };

            settings.Setup(s => s.GetValue("deployment", "branch")).Returns("my-branch");
            var deploymentSettings = new DeploymentSettingsManager(settings.Object, BuildSettingsProviders(defaultSettings));

            // Act
            string branch = deploymentSettings.GetBranch();

            // Assert
            Assert.Equal("my-branch", branch);
        }
コード例 #8
0
ファイル: NinjectServices.cs プロジェクト: zhanglinalove/kudu
        private static void RegisterServices(IKernel kernel)
        {
            var serverConfiguration = new ServerConfiguration();

            // Make sure %HOME% is correctly set
            EnsureHomeEnvironmentVariable();

            EnsureSiteBitnessEnvironmentVariable();

            IEnvironment environment = GetEnvironment();

            EnsureDotNetCoreEnvironmentVariable(environment);

            // Add various folders that never change to the process path. All child processes will inherit
            PrependFoldersToPath(environment);

            // Per request environment
            kernel.Bind <IEnvironment>().ToMethod(context => GetEnvironment(context.Kernel.Get <IDeploymentSettingsManager>(), HttpContext.Current))
            .InRequestScope();

            // General
            kernel.Bind <IServerConfiguration>().ToConstant(serverConfiguration);

            kernel.Bind <IBuildPropertyProvider>().ToConstant(new BuildPropertyProvider());

            System.Func <ITracer> createTracerThunk = () => GetTracer(kernel);

            // First try to use the current request profiler if any, otherwise create a new one
            var traceFactory = new TracerFactory(() => TraceServices.CurrentRequestTracer ?? createTracerThunk());

            kernel.Bind <ITracer>().ToMethod(context => TraceServices.CurrentRequestTracer ?? NullTracer.Instance);
            kernel.Bind <ITraceFactory>().ToConstant(traceFactory);
            TraceServices.SetTraceFactory(createTracerThunk);

            // Setup the deployment lock
            string lockPath           = Path.Combine(environment.SiteRootPath, Constants.LockPath);
            string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile);
            string statusLockPath     = Path.Combine(lockPath, Constants.StatusLockFile);
            string sshKeyLockPath     = Path.Combine(lockPath, Constants.SSHKeyLockFile);
            string hooksLockPath      = Path.Combine(lockPath, Constants.HooksLockFile);

            _deploymentLock = new DeploymentLockFile(deploymentLockPath, kernel.Get <ITraceFactory>());
            _deploymentLock.InitializeAsyncLocks();

            var statusLock = new LockFile(statusLockPath, kernel.Get <ITraceFactory>());
            var sshKeyLock = new LockFile(sshKeyLockPath, kernel.Get <ITraceFactory>());
            var hooksLock  = new LockFile(hooksLockPath, kernel.Get <ITraceFactory>());

            kernel.Bind <IOperationLock>().ToConstant(sshKeyLock).WhenInjectedInto <SSHKeyController>();
            kernel.Bind <IOperationLock>().ToConstant(statusLock).WhenInjectedInto <DeploymentStatusManager>();
            kernel.Bind <IOperationLock>().ToConstant(hooksLock).WhenInjectedInto <WebHooksManager>();
            kernel.Bind <IOperationLock>().ToConstant(_deploymentLock);

            var shutdownDetector = new ShutdownDetector();

            shutdownDetector.Initialize();

            IDeploymentSettingsManager noContextDeploymentsSettingsManager =
                new DeploymentSettingsManager(new XmlSettings.Settings(GetSettingsPath(environment)));

            TraceServices.TraceLevel = noContextDeploymentsSettingsManager.GetTraceLevel();

            var noContextTraceFactory = new TracerFactory(() => GetTracerWithoutContext(environment, noContextDeploymentsSettingsManager));
            var etwTraceFactory       = new TracerFactory(() => new ETWTracer(string.Empty, string.Empty));

            kernel.Bind <IAnalytics>().ToMethod(context => new Analytics(context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                         context.Kernel.Get <IServerConfiguration>(),
                                                                         noContextTraceFactory));

            // Trace unhandled (crash) exceptions.
            AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
            {
                var ex = args.ExceptionObject as Exception;
                if (ex != null)
                {
                    kernel.Get <IAnalytics>().UnexpectedException(ex);
                }
            };

            // Trace shutdown event
            // Cannot use shutdownDetector.Token.Register because of race condition
            // with NinjectServices.Stop via WebActivator.ApplicationShutdownMethodAttribute
            Shutdown += () => TraceShutdown(environment, noContextDeploymentsSettingsManager);

            // LogStream service
            // The hooks and log stream start endpoint are low traffic end-points. Re-using it to avoid creating another lock
            var logStreamManagerLock = hooksLock;

            kernel.Bind <LogStreamManager>().ToMethod(context => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath),
                                                                                      context.Kernel.Get <IEnvironment>(),
                                                                                      context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                      context.Kernel.Get <ITracer>(),
                                                                                      shutdownDetector,
                                                                                      logStreamManagerLock));

            kernel.Bind <InfoRefsController>().ToMethod(context => new InfoRefsController(t => context.Kernel.Get(t)))
            .InRequestScope();

            kernel.Bind <CustomGitRepositoryHandler>().ToMethod(context => new CustomGitRepositoryHandler(t => context.Kernel.Get(t)))
            .InRequestScope();

            // Deployment Service
            kernel.Bind <ISettings>().ToMethod(context => new XmlSettings.Settings(GetSettingsPath(environment)))
            .InRequestScope();
            kernel.Bind <IDeploymentSettingsManager>().To <DeploymentSettingsManager>()
            .InRequestScope();

            kernel.Bind <IDeploymentStatusManager>().To <DeploymentStatusManager>()
            .InRequestScope();

            kernel.Bind <ISiteBuilderFactory>().To <SiteBuilderFactory>()
            .InRequestScope();

            kernel.Bind <IWebHooksManager>().To <WebHooksManager>()
            .InRequestScope();

            ITriggeredJobsManager triggeredJobsManager = new TriggeredJobsManager(
                etwTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>(),
                kernel.Get <IWebHooksManager>());

            kernel.Bind <ITriggeredJobsManager>().ToConstant(triggeredJobsManager)
            .InTransientScope();

            TriggeredJobsScheduler triggeredJobsScheduler = new TriggeredJobsScheduler(
                triggeredJobsManager,
                etwTraceFactory,
                environment,
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>());

            kernel.Bind <TriggeredJobsScheduler>().ToConstant(triggeredJobsScheduler)
            .InTransientScope();

            IContinuousJobsManager continuousJobManager = new ContinuousJobsManager(
                etwTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>());

            OperationManager.SafeExecute(triggeredJobsManager.CleanupDeletedJobs);
            OperationManager.SafeExecute(continuousJobManager.CleanupDeletedJobs);

            kernel.Bind <IContinuousJobsManager>().ToConstant(continuousJobManager)
            .InTransientScope();

            kernel.Bind <ILogger>().ToMethod(context => GetLogger(environment, context.Kernel))
            .InRequestScope();

            kernel.Bind <IDeploymentManager>().To <DeploymentManager>()
            .InRequestScope();
            kernel.Bind <IFetchDeploymentManager>().To <FetchDeploymentManager>()
            .InRequestScope();
            kernel.Bind <ISSHKeyManager>().To <SSHKeyManager>()
            .InRequestScope();

            kernel.Bind <IRepositoryFactory>().ToMethod(context => _deploymentLock.RepositoryFactory = new RepositoryFactory(context.Kernel.Get <IEnvironment>(),
                                                                                                                             context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                                                             context.Kernel.Get <ITraceFactory>()))
            .InRequestScope();

            kernel.Bind <IApplicationLogsReader>().To <ApplicationLogsReader>()
            .InSingletonScope();

            // Git server
            kernel.Bind <IDeploymentEnvironment>().To <DeploymentEnvrionment>();

            kernel.Bind <IGitServer>().ToMethod(context => new GitExeServer(context.Kernel.Get <IEnvironment>(),
                                                                            _deploymentLock,
                                                                            GetRequestTraceFile(context.Kernel),
                                                                            context.Kernel.Get <IRepositoryFactory>(),
                                                                            context.Kernel.Get <IDeploymentEnvironment>(),
                                                                            context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                            context.Kernel.Get <ITraceFactory>()))
            .InRequestScope();

            // Git Servicehook parsers
            kernel.Bind <IServiceHookHandler>().To <GenericHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <BitbucketHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <BitbucketHandlerV2>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <DropboxHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodePlexHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodebaseHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitlabHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubCompatHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <KilnHgHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <VSOHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <OneDriveHandler>().InRequestScope();

            // SiteExtensions
            kernel.Bind <ISiteExtensionManager>().To <SiteExtensionManager>().InRequestScope();

            // Functions
            kernel.Bind <IFunctionManager>().To <FunctionManager>().InRequestScope();

            // Command executor
            kernel.Bind <ICommandExecutor>().To <CommandExecutor>().InRequestScope();

            MigrateSite(environment, noContextDeploymentsSettingsManager);
            RemoveOldTracePath(environment);
            RemoveTempFileFromUserDrive(environment);

            // Temporary fix for https://github.com/npm/npm/issues/5905
            EnsureNpmGlobalDirectory();
            EnsureUserProfileDirectory();

            // Skip SSL Certificate Validate
            if (Kudu.Core.Environment.SkipSslValidation)
            {
                ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); };
            }

            // Make sure webpages:Enabled is true. Even though we set it in web.config, it could be overwritten by
            // an Azure AppSetting that's supposed to be for the site only but incidently affects Kudu as well.
            ConfigurationManager.AppSettings["webpages:Enabled"] = "true";

            // Kudu does not rely owin:appStartup.  This is to avoid Azure AppSetting if set.
            if (ConfigurationManager.AppSettings["owin:appStartup"] != null)
            {
                // Set the appSetting to null since we cannot use AppSettings.Remove(key) (ReadOnly exception!)
                ConfigurationManager.AppSettings["owin:appStartup"] = null;
            }

            RegisterRoutes(kernel, RouteTable.Routes);

            // Register the default hubs route: ~/signalr
            GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(kernel);
            GlobalConfiguration.Configuration.Filters.Add(
                new TraceDeprecatedActionAttribute(
                    kernel.Get <IAnalytics>(),
                    kernel.Get <ITraceFactory>()));
            GlobalConfiguration.Configuration.Filters.Add(new EnsureRequestIdHandlerAttribute());
        }
コード例 #9
0
        private static int Main(string[] args)
        {
            // Turn flag on in app.config to wait for debugger on launch
            if (ConfigurationManager.AppSettings["WaitForDebuggerOnStart"] == "true")
            {
                while (!Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }

            if (System.Environment.GetEnvironmentVariable(SettingsKeys.DisableDeploymentOnPush) == "1")
            {
                return(0);
            }

            if (args.Length < 2)
            {
                System.Console.WriteLine("Usage: kudu.exe appRoot wapTargets [deployer]");
                return(1);
            }

            // The post receive hook launches the exe from sh and intereprets newline differently.
            // This fixes very wacky issues with how the output shows up in the console on push
            System.Console.Error.NewLine = "\n";
            System.Console.Out.NewLine   = "\n";

            System.Environment.SetEnvironmentVariable("GIT_DIR", null, System.EnvironmentVariableTarget.Process);

            // Skip SSL Certificate Validate
            OperationClient.SkipSslValidationIfNeeded();

            string appRoot    = args[0];
            string wapTargets = args[1];
            string deployer   = args.Length == 2 ? null : args[2];

            IEnvironment env      = GetEnvironment(appRoot);
            ISettings    settings = new XmlSettings.Settings(GetSettingsPath(env));
            IDeploymentSettingsManager settingsManager = new DeploymentSettingsManager(settings);

            // Adjust repo path
            env.RepositoryPath = Path.Combine(env.SiteRootPath, settingsManager.GetRepositoryPath());

            // Setup the trace
            TraceLevel    level        = settingsManager.GetTraceLevel();
            ITracer       tracer       = GetTracer(env, level);
            ITraceFactory traceFactory = new TracerFactory(() => tracer);

            // Calculate the lock path
            string lockPath           = Path.Combine(env.SiteRootPath, Constants.LockPath);
            string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile);
            string statusLockPath     = Path.Combine(lockPath, Constants.StatusLockFile);
            string hooksLockPath      = Path.Combine(lockPath, Constants.HooksLockFile);

            IOperationLock deploymentLock = new LockFile(deploymentLockPath, traceFactory);
            IOperationLock statusLock     = new LockFile(statusLockPath, traceFactory);
            IOperationLock hooksLock      = new LockFile(hooksLockPath, traceFactory);

            IBuildPropertyProvider buildPropertyProvider = new BuildPropertyProvider();
            ISiteBuilderFactory    builderFactory        = new SiteBuilderFactory(buildPropertyProvider, env);

            IRepository gitRepository;

            if (settingsManager.UseLibGit2SharpRepository())
            {
                gitRepository = new LibGit2SharpRepository(env, settingsManager, traceFactory);
            }
            else
            {
                gitRepository = new GitExeRepository(env, settingsManager, traceFactory);
            }

            IServerConfiguration serverConfiguration = new ServerConfiguration();
            IAnalytics           analytics           = new Analytics(settingsManager, serverConfiguration, traceFactory);

            IWebHooksManager         hooksManager            = new WebHooksManager(tracer, env, hooksLock);
            IDeploymentStatusManager deploymentStatusManager = new DeploymentStatusManager(env, analytics, statusLock);
            IAutoSwapHandler         autoSwapHander          = new AutoSwapHandler(deploymentStatusManager, env, settingsManager, traceFactory);
            var functionManager = new FunctionManager(env, traceFactory);
            var logger          = new ConsoleLogger();
            IDeploymentManager deploymentManager = new DeploymentManager(builderFactory,
                                                                         env,
                                                                         traceFactory,
                                                                         analytics,
                                                                         settingsManager,
                                                                         deploymentStatusManager,
                                                                         deploymentLock,
                                                                         GetLogger(env, level, logger),
                                                                         hooksManager,
                                                                         autoSwapHander,
                                                                         functionManager);

            var step = tracer.Step(XmlTracer.ExecutingExternalProcessTrace, new Dictionary <string, string>
            {
                { "type", "process" },
                { "path", "kudu.exe" },
                { "arguments", appRoot + " " + wapTargets }
            });

            using (step)
            {
                try
                {
                    deploymentManager.DeployAsync(gitRepository, changeSet: null, deployer: deployer, clean: false)
                    .Wait();
                }
                catch (Exception e)
                {
                    tracer.TraceError(e);

                    System.Console.Error.WriteLine(e.GetBaseException().Message);
                    System.Console.Error.WriteLine(Resources.Log_DeploymentError);
                    return(1);
                }
            }

            if (logger.HasErrors)
            {
                System.Console.Error.WriteLine(Resources.Log_DeploymentError);
                return(1);
            }

            return(0);
        }
コード例 #10
0
        private static int Main(string[] args)
        {
            // Turn flag on in app.config to wait for debugger on launch
            if (ConfigurationManager.AppSettings["WaitForDebuggerOnStart"] == "true")
            {
                while (!Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }

            if (System.Environment.GetEnvironmentVariable(SettingsKeys.DisableDeploymentOnPush) == "1")
            {
                return(0);
            }

            if (args.Length < 2)
            {
                System.Console.WriteLine("Usage: kudu.exe appRoot wapTargets [deployer]");
                return(1);
            }

            // The post receive hook launches the exe from sh and interprets newline differently.
            // This fixes very wacky issues with how the output shows up in the console on push
            System.Console.Error.NewLine = "\n";
            System.Console.Out.NewLine   = "\n";

            string appRoot    = args[0];
            string wapTargets = args[1];
            string deployer   = args.Length == 2 ? null : args[2];
            string requestId  = System.Environment.GetEnvironmentVariable(Constants.RequestIdHeader);

            IEnvironment env      = GetEnvironment(appRoot, requestId);
            ISettings    settings = new XmlSettings.Settings(GetSettingsPath(env));
            IDeploymentSettingsManager settingsManager = new DeploymentSettingsManager(settings);

            // Setup the trace
            TraceLevel    level        = settingsManager.GetTraceLevel();
            ITracer       tracer       = GetTracer(env, level);
            ITraceFactory traceFactory = new TracerFactory(() => tracer);

            // Calculate the lock path
            string lockPath           = Path.Combine(env.SiteRootPath, Constants.LockPath);
            string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile);

            IOperationLock deploymentLock = new LockFile(deploymentLockPath, traceFactory);

            if (deploymentLock.IsHeld)
            {
                return(PerformDeploy(appRoot, wapTargets, deployer, lockPath, env, settingsManager, level, tracer, traceFactory, deploymentLock));
            }

            // Cross child process lock is not working on linux via mono.
            // When we reach here, deployment lock must be HELD! To solve above issue, we lock again before continue.
            try
            {
                return(deploymentLock.LockOperation(() =>
                {
                    return PerformDeploy(appRoot, wapTargets, deployer, lockPath, env, settingsManager, level, tracer, traceFactory, deploymentLock);
                }, "Performing deployment", TimeSpan.Zero));
            }
            catch (LockOperationException)
            {
                return(-1);
            }
        }
コード例 #11
0
ファイル: NinjectServices.cs プロジェクト: hanwesh/kudu
        private static void RegisterServices(IKernel kernel)
        {
            var serverConfiguration = new ServerConfiguration();

            // Make sure %HOME% is correctly set
            EnsureHomeEnvironmentVariable();

            IEnvironment environment = GetEnvironment();

            // Per request environment
            kernel.Bind <IEnvironment>().ToMethod(context => GetEnvironment(context.Kernel.Get <IDeploymentSettingsManager>()))
            .InRequestScope();

            // General
            kernel.Bind <HttpContextBase>().ToMethod(context => new HttpContextWrapper(HttpContext.Current))
            .InRequestScope();
            kernel.Bind <IServerConfiguration>().ToConstant(serverConfiguration);

            kernel.Bind <IBuildPropertyProvider>().ToConstant(new BuildPropertyProvider());

            System.Func <ITracer> createTracerThunk = () => GetTracer(environment, kernel);
            System.Func <ILogger> createLoggerThunk = () => GetLogger(environment, kernel);

            // First try to use the current request profiler if any, otherwise create a new one
            var traceFactory = new TracerFactory(() => TraceServices.CurrentRequestTracer ?? createTracerThunk());

            kernel.Bind <ITracer>().ToMethod(context => TraceServices.CurrentRequestTracer ?? NullTracer.Instance);
            kernel.Bind <ITraceFactory>().ToConstant(traceFactory);
            TraceServices.SetTraceFactory(createTracerThunk, createLoggerThunk);

            // Setup the deployment lock
            string lockPath           = Path.Combine(environment.SiteRootPath, Constants.LockPath);
            string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile);
            string statusLockPath     = Path.Combine(lockPath, Constants.StatusLockFile);
            string sshKeyLockPath     = Path.Combine(lockPath, Constants.SSHKeyLockFile);
            string hooksLockPath      = Path.Combine(lockPath, Constants.HooksLockFile);

            _deploymentLock = new DeploymentLockFile(deploymentLockPath, kernel.Get <ITraceFactory>());
            _deploymentLock.InitializeAsyncLocks();

            var statusLock = new LockFile(statusLockPath, kernel.Get <ITraceFactory>());
            var sshKeyLock = new LockFile(sshKeyLockPath, kernel.Get <ITraceFactory>());
            var hooksLock  = new LockFile(hooksLockPath, kernel.Get <ITraceFactory>());

            kernel.Bind <IOperationLock>().ToConstant(sshKeyLock).WhenInjectedInto <SSHKeyController>();
            kernel.Bind <IOperationLock>().ToConstant(statusLock).WhenInjectedInto <DeploymentStatusManager>();
            kernel.Bind <IOperationLock>().ToConstant(hooksLock).WhenInjectedInto <WebHooksManager>();
            kernel.Bind <IOperationLock>().ToConstant(_deploymentLock);

            kernel.Bind <IAnalytics>().ToMethod(context => new Analytics(context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                         context.Kernel.Get <ITracer>(),
                                                                         environment.AnalyticsPath));

            var shutdownDetector = new ShutdownDetector();

            shutdownDetector.Initialize();

            IDeploymentSettingsManager noContextDeploymentsSettingsManager =
                new DeploymentSettingsManager(new XmlSettings.Settings(GetSettingsPath(environment)));

            // Trace shutdown event
            // Cannot use shutdownDetector.Token.Register because of race condition
            // with NinjectServices.Stop via WebActivator.ApplicationShutdownMethodAttribute
            Shutdown += () => TraceShutdown(environment, noContextDeploymentsSettingsManager);

            // LogStream service
            // The hooks and log stream start endpoint are low traffic end-points. Re-using it to avoid creating another lock
            var logStreamManagerLock = hooksLock;

            kernel.Bind <LogStreamManager>().ToMethod(context => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath),
                                                                                      context.Kernel.Get <IEnvironment>(),
                                                                                      context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                      context.Kernel.Get <ITracer>(),
                                                                                      shutdownDetector,
                                                                                      logStreamManagerLock));

            kernel.Bind <InfoRefsController>().ToMethod(context => new InfoRefsController(t => context.Kernel.Get(t)))
            .InRequestScope();

            kernel.Bind <CustomGitRepositoryHandler>().ToMethod(context => new CustomGitRepositoryHandler(t => context.Kernel.Get(t)))
            .InRequestScope();

            // Deployment Service
            kernel.Bind <ISettings>().ToMethod(context => new XmlSettings.Settings(GetSettingsPath(environment)))
            .InRequestScope();
            kernel.Bind <IDeploymentSettingsManager>().To <DeploymentSettingsManager>()
            .InRequestScope();

            kernel.Bind <IDeploymentStatusManager>().To <DeploymentStatusManager>()
            .InRequestScope();

            kernel.Bind <ISiteBuilderFactory>().To <SiteBuilderFactory>()
            .InRequestScope();

            kernel.Bind <IWebHooksManager>().To <WebHooksManager>()
            .InRequestScope();

            var noContextTraceFactory = new TracerFactory(() => GetTracerWithoutContext(environment, noContextDeploymentsSettingsManager));

            ITriggeredJobsManager triggeredJobsManager = new TriggeredJobsManager(
                noContextTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>(),
                kernel.Get <IWebHooksManager>());

            kernel.Bind <ITriggeredJobsManager>().ToConstant(triggeredJobsManager)
            .InTransientScope();

            IContinuousJobsManager continuousJobManager = new ContinuousJobsManager(
                noContextTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>());

            kernel.Bind <IContinuousJobsManager>().ToConstant(continuousJobManager)
            .InTransientScope();

            kernel.Bind <ILogger>().ToMethod(context => GetLogger(environment, context.Kernel))
            .InRequestScope();

            kernel.Bind <IRepository>().ToMethod(context => new GitExeRepository(context.Kernel.Get <IEnvironment>(),
                                                                                 context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                 context.Kernel.Get <ITraceFactory>()))
            .InRequestScope();

            kernel.Bind <IDeploymentManager>().To <DeploymentManager>()
            .InRequestScope();
            kernel.Bind <ISSHKeyManager>().To <SSHKeyManager>()
            .InRequestScope();

            kernel.Bind <IRepositoryFactory>().ToMethod(context => _deploymentLock.RepositoryFactory = new RepositoryFactory(context.Kernel.Get <IEnvironment>(),
                                                                                                                             context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                                                             context.Kernel.Get <ITraceFactory>(),
                                                                                                                             context.Kernel.Get <HttpContextBase>()))
            .InRequestScope();

            kernel.Bind <IApplicationLogsReader>().To <ApplicationLogsReader>()
            .InSingletonScope();

            // Git server
            kernel.Bind <IDeploymentEnvironment>().To <DeploymentEnvrionment>();

            kernel.Bind <IGitServer>().ToMethod(context => new GitExeServer(context.Kernel.Get <IEnvironment>(),
                                                                            _deploymentLock,
                                                                            GetRequestTraceFile(context.Kernel),
                                                                            context.Kernel.Get <IRepositoryFactory>(),
                                                                            context.Kernel.Get <IDeploymentEnvironment>(),
                                                                            context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                            context.Kernel.Get <ITraceFactory>()))
            .InRequestScope();

            // Git Servicehook parsers
            kernel.Bind <IServiceHookHandler>().To <GenericHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <BitbucketHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <DropboxHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodePlexHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodebaseHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitlabHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubCompatHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <KilnHgHandler>().InRequestScope();

            // SiteExtensions
            kernel.Bind <ISiteExtensionManager>().To <SiteExtensionManager>().InRequestScope();

            // Command executor
            kernel.Bind <ICommandExecutor>().ToMethod(context => GetCommandExecutor(environment, context))
            .InRequestScope();

            MigrateSite(environment, noContextDeploymentsSettingsManager);

            RegisterRoutes(kernel, RouteTable.Routes);

            // Register the default hubs route: ~/signalr
            GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(kernel);
            RouteTable.Routes.MapConnection <PersistentCommandController>("commandstream", "/commandstream");
            RouteTable.Routes.MapHubs("/filesystemhub", new HubConfiguration());
        }
コード例 #12
0
ファイル: Program.cs プロジェクト: ashbrener/kudu
        static int Main(string[] args)
        {
            // Turn flag on in app.config to wait for debugger on launch
            if (ConfigurationManager.AppSettings["WaitForDebuggerOnStart"] == "true")
            {
                while (!Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }

            if (args.Length < 2)
            {
                System.Console.WriteLine("Usage: kudu.exe appRoot wapTargets [deployer]");
                return(1);
            }

            // The post receive hook launches the exe from sh and intereprets newline differently.
            // This fixes very wacky issues with how the output shows up in the conosle on push
            System.Console.Error.NewLine = "\n";
            System.Console.Out.NewLine   = "\n";

            System.Environment.SetEnvironmentVariable("GIT_DIR", null, System.EnvironmentVariableTarget.Process);

            var    appRoot        = args[0];
            var    wapTargets     = args[1];
            string deployer       = args.Length == 2 ? null : args[2];
            string nugetCachePath = null;

            IEnvironment env             = GetEnvironment(appRoot, nugetCachePath);
            var          settings        = new XmlSettings.Settings(GetSettingsPath(env));
            var          settingsManager = new DeploymentSettingsManager(settings);

            // Setup the trace
            TraceLevel level        = settingsManager.GetTraceLevel();
            var        tracer       = GetTracer(env, level);
            var        traceFactory = new TracerFactory(() => tracer);

            // Calculate the lock path
            string lockPath           = Path.Combine(env.SiteRootPath, Constants.LockPath);
            string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile);
            var    deploymentLock     = new LockFile(traceFactory, deploymentLockPath);

            var fs = new FileSystem();
            var buildPropertyProvider = new BuildPropertyProvider();
            var serverRepository      = new GitDeploymentRepository(env.RepositoryPath, env.SiteRootPath, traceFactory);
            var builderFactory        = new SiteBuilderFactory(settingsManager, buildPropertyProvider, env);

            var logger            = new ConsoleLogger();
            var deploymentManager = new DeploymentManager(serverRepository,
                                                          builderFactory,
                                                          env,
                                                          fs,
                                                          traceFactory,
                                                          settingsManager,
                                                          deploymentLock,
                                                          GetLogger(env, level, logger));

            var step = tracer.Step("Executing external process", new Dictionary <string, string>
            {
                { "type", "process" },
                { "path", "kudu.exe" },
                { "arguments", appRoot + " " + wapTargets }
            });

            using (step)
            {
                try
                {
                    deploymentManager.Deploy(deployer);
                }
                catch
                {
                    System.Console.Error.WriteLine(Resources.Log_DeploymentError);

                    throw;
                }
            }

            if (logger.HasErrors)
            {
                System.Console.Error.WriteLine(Resources.Log_DeploymentError);
                return(1);
            }

            return(0);
        }
コード例 #13
0
ファイル: Startup.cs プロジェクト: JennyLawrance/KuduLight
        /// <summary>
        /// This method gets called by the runtime. It is used to add services
        /// to the container. It uses the Extension pattern.
        /// </summary>
        /// <todo>
        ///   CORE TODO Remove initializing contextAccessor : This is new. See if over time we can refactor away the need for this?
        ///   It's kind of a quick hack/compatibility shim. Ideally you want to get the request context only from where
        ///   it's specifically provided to you (Request.HttpContext in a controller, or as an Invoke() parameter in
        ///   a middleware) and pass it wherever its needed.
        /// </todo>
        public void ConfigureServices(IServiceCollection services)
        {
            Console.WriteLine("\nConfigure Services : " + DateTime.Now.ToString("hh.mm.ss.ffffff"));

            services.Configure <FormOptions>(options =>
            {
                options.MultipartBodyLengthLimit = 52428800;
                options.ValueCountLimit          = 500000;
                options.KeyLengthLimit           = 500000;
            });


            services.AddMvcCore()
            .AddRazorPages()
            .AddAuthorization()
            .AddFormatterMappings()
            .AddJsonFormatters()
            .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());


            services.AddGZipCompression();

            services.AddDirectoryBrowser();

            services.AddDataProtection();

            var contextAccessor = new HttpContextAccessor();

            this._httpContextAccessor = contextAccessor;
            services.AddSingleton <IHttpContextAccessor>(contextAccessor);

            KuduWebUtil.EnsureHomeEnvironmentVariable();

            KuduWebUtil.EnsureSiteBitnessEnvironmentVariable();

            IEnvironment environment = KuduWebUtil.GetEnvironment(_hostingEnvironment);

            _webAppEnvironment = environment;

            KuduWebUtil.EnsureDotNetCoreEnvironmentVariable(environment);

            //CORE TODO Check this
            // fix up invalid /home/site/deployments/settings.xml
            KuduWebUtil.EnsureValidDeploymentXmlSettings(environment);

            // Add various folders that never change to the process path. All child processes will inherit this
            KuduWebUtil.PrependFoldersToPath(environment);

            // General
            services.AddSingleton <IServerConfiguration>(serverConfiguration);

            // CORE TODO Looks like this doesn't ever actually do anything, can refactor out?
            services.AddSingleton <IBuildPropertyProvider>(new BuildPropertyProvider());


            IDeploymentSettingsManager noContextDeploymentsSettingsManager =
                new DeploymentSettingsManager(new XmlSettings.Settings(KuduWebUtil.GetSettingsPath(environment)));

            TraceServices.TraceLevel = noContextDeploymentsSettingsManager.GetTraceLevel();

            // Per request environment
            services.AddScoped <IEnvironment>(sp => KuduWebUtil.GetEnvironment(_hostingEnvironment, sp.GetRequiredService <IDeploymentSettingsManager>(),
                                                                               sp.GetRequiredService <IHttpContextAccessor>().HttpContext));

            services.AddDeployementServices(environment);


            /*
             * CORE TODO all this business around ITracerFactory/ITracer/GetTracer()/
             * ILogger needs serious refactoring:
             * - Names should be changed to make it clearer that ILogger is for deployment
             * logging and ITracer and friends are for Kudu tracing
             * - ILogger is a first-class citizen in .NET core and has it's own meaning. We should be using it
             *   where appropriate (and not name-colliding with it)
             * - ITracer vs. ITraceFactory is redundant and confusing.
             * - All this stuff with funcs and factories and TraceServices is overcomplicated.
             * TraceServices only serves to confuse stuff now that we're avoiding
             */
            Func <IServiceProvider, ITracer> resolveTracer = sp => KuduWebUtil.GetTracer(sp);

            ITracer CreateTracerThunk() => resolveTracer(services.BuildServiceProvider());

            // First try to use the current request profiler if any, otherwise create a new one
            var traceFactory = new TracerFactory(() => {
                var sp      = services.BuildServiceProvider();
                var context = sp.GetRequiredService <IHttpContextAccessor>().HttpContext;
                return(TraceServices.GetRequestTracer(context) ?? resolveTracer(sp));
            });

            services.AddScoped <ITracer>(sp =>
            {
                var context = sp.GetRequiredService <IHttpContextAccessor>().HttpContext;
                return(TraceServices.GetRequestTracer(context) ?? NullTracer.Instance);
            });

            services.AddSingleton <ITraceFactory>(traceFactory);

            TraceServices.SetTraceFactory(CreateTracerThunk);

            services.AddSingleton <IDictionary <string, IOperationLock> >(KuduWebUtil.GetNamedLocks(traceFactory, environment));

            // CORE TODO ShutdownDetector, used by LogStreamManager.
            //var shutdownDetector = new ShutdownDetector();
            //shutdownDetector.Initialize()

            var noContextTraceFactory = new TracerFactory(() => KuduWebUtil.GetTracerWithoutContext(environment, noContextDeploymentsSettingsManager));
            var etwTraceFactory       = new TracerFactory(() => new ETWTracer(string.Empty, string.Empty));

            services.AddTransient <IAnalytics>(sp => new Analytics(sp.GetRequiredService <IDeploymentSettingsManager>(),
                                                                   sp.GetRequiredService <IServerConfiguration>(),
                                                                   noContextTraceFactory));

            // CORE TODO Trace unhandled exceptions
            //AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
            //{
            //    var ex = args.ExceptionObject as Exception;
            //    if (ex != null)
            //    {
            //        kernel.Get<IAnalytics>().UnexpectedException(ex);
            //    }
            //};

            // CORE TODO
            // Trace shutdown event
            // Cannot use shutdownDetector.Token.Register because of race condition
            // with NinjectServices.Stop via WebActivator.ApplicationShutdownMethodAttribute
            //Shutdown += () => TraceShutdown(environment, noContextDeploymentsSettingsManager);

            // CORE TODO
            // LogStream service
            // The hooks and log stream start endpoint are low traffic end-points. Re-using it to avoid creating another lock
            var logStreamManagerLock = KuduWebUtil.GetNamedLocks(traceFactory, environment)["hooks"];

            //kernel.Bind<LogStreamManager>().ToMethod(context => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath),
            //                                                                         context.Kernel.Get<IEnvironment>(),
            //                                                                         context.Kernel.Get<IDeploymentSettingsManager>(),
            //                                                                         context.Kernel.Get<ITracer>(),
            //                                                                         shutdownDetector,
            //                                                                         logStreamManagerLock));

            services.AddTransient(sp => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath),
                                                             sp.GetRequiredService <IEnvironment>(),
                                                             sp.GetRequiredService <IDeploymentSettingsManager>(),
                                                             sp.GetRequiredService <ITracer>(),
                                                             logStreamManagerLock));

            // CORE TODO Need to implement this, and same comment as in InfoRefsController.cs (not sure why it needs the kernel/iserviceprovider as a
            // service locator, why does it need "delayed binding"?)
            //kernel.Bind<CustomGitRepositoryHandler>().ToMethod(context => new CustomGitRepositoryHandler(t => context.Kernel.Get(t)))
            //                                         .InRequestScope();

            // Deployment Service

            services.AddWebJobsDependencies();

            services.AddScoped <ILogger>(sp => KuduWebUtil.GetLogger(sp));

            services.AddScoped <IDeploymentManager, DeploymentManager>();
            services.AddScoped <IFetchDeploymentManager, FetchDeploymentManager>();
            services.AddScoped <ISSHKeyManager, SSHKeyManager>();

            services.AddScoped <IRepositoryFactory>(sp => KuduWebUtil.GetDeploymentLock(traceFactory, environment).RepositoryFactory = new RepositoryFactory(
                                                        sp.GetRequiredService <IEnvironment>(), sp.GetRequiredService <IDeploymentSettingsManager>(), sp.GetRequiredService <ITraceFactory>()));

            // CORE NOTE This was previously wired up in Ninject with .InSingletonScope. I'm not sure how that worked,
            // since it depends on an IEnvironment, which was set up with .PerRequestScope. I have made this per request.
            services.AddScoped <IApplicationLogsReader, ApplicationLogsReader>();

            // Git server
            services.AddGitServer(KuduWebUtil.GetDeploymentLock(traceFactory, environment));

            // Git Servicehook Parsers
            services.AddGitServiceHookParsers();

            // CORE TODO
            // SiteExtensions
            //kernel.Bind<ISiteExtensionManager>().To<SiteExtensionManager>().InRequestScope();

            // CORE TODO
            // Functions
            //kernel.Bind<IFunctionManager>().To<FunctionManager>().InRequestScope();

            services.AddScoped <ICommandExecutor, CommandExecutor>();

            // CORE TODO This stuff should probably go in a separate method
            // (they don't really fit into "ConfigureServices"), and much of it is probably no longer needed
            //MigrateSite(environment, noContextDeploymentsSettingsManager);
            //RemoveOldTracePath(environment);
            //RemoveTempFileFromUserDrive(environment);

            //// Temporary fix for https://github.com/npm/npm/issues/5905
            //EnsureNpmGlobalDirectory();
            //EnsureUserProfileDirectory();

            //// Skip SSL Certificate Validate
            //if (Kudu.Core.Environment.SkipSslValidation)
            //{
            //     ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            //}

            //// Make sure webpages:Enabled is true. Even though we set it in web.config, it could be overwritten by
            //// an Azure AppSetting that's supposed to be for the site only but incidently affects Kudu as well.
            ConfigurationManager.AppSettings["webpages:Enabled"] = "true";

            //// Kudu does not rely owin:appStartup.  This is to avoid Azure AppSetting if set.
            if (ConfigurationManager.AppSettings?["owin:appStartup"] != null)
            {
                // Set the appSetting to null since we cannot use AppSettings.Remove(key) (ReadOnly exception!)
                ConfigurationManager.AppSettings["owin:appStartup"] = null;
            }

            //RegisterRoutes(kernel, RouteTable.Routes);

            //// Register the default hubs route: ~/signalr
            //GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(kernel);
            //GlobalConfiguration.Configuration.Filters.Add(
            //    new TraceDeprecatedActionAttribute(
            //        kernel.Get<IAnalytics>(),
            //        kernel.Get<ITraceFactory>()));
            //GlobalConfiguration.Configuration.Filters.Add(new EnsureRequestIdHandlerAttribute());

            //FileTarget target = LogManager.Configuration.FindTargetByName("file") as FileTarget;
            //String logfile = _webAppEnvironment.LogFilesPath + "/.txt";
            //target.FileName = logfile;
        }