public void LockFileConcurrentTest() { // Mock var file = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); var lockFile = new LockFile(file, NullTracerFactory.Instance); int count = 10; int threads = 2; int totals = 0; // Test var result = Parallel.For(0, threads, i => { for (int j = 0; j < count; ++j) { lockFile.LockOperation(() => { // simulate get/set int val = totals; Thread.Sleep(0); totals = val + 1; using (var reader = new StreamReader(FileSystemHelpers.OpenFile(file, FileMode.Open, FileAccess.Read, FileShare.Write))) { Assert.Contains("at Kudu.Core.Test.LockFileTests", reader.ReadToEnd()); } }, TimeSpan.FromSeconds(60)); } }); // Assert Assert.True(result.IsCompleted); Assert.Equal(count * threads, totals); FileSystemHelpers.DeleteFileSafe(file); }
public ContinuousJobRunner(ContinuousJob continuousJob, IEnvironment environment, IDeploymentSettingsManager settings, ITraceFactory traceFactory, IAnalytics analytics) : base(continuousJob.Name, Constants.ContinuousPath, environment, settings, traceFactory, analytics) { _continuousJobLogger = new ContinuousJobLogger(continuousJob.Name, Environment, TraceFactory); _disableFilePath = Path.Combine(continuousJob.JobBinariesRootPath, "disable.job"); _singletonLock = new LockFile(Path.Combine(JobDataPath, "singleton.job.lock"), TraceFactory); }
/// <summary> /// Stops the application. /// </summary> public static void Stop() { if (Shutdown != null) { Shutdown(); } if (_deploymentLock != null) { _deploymentLock.TerminateAsyncLocks(); _deploymentLock = null; } _bootstrapper.ShutDown(); }
private static ITracer GetTracer(IEnvironment env, TraceLevel level, IFileSystem fileSystem) { if (level > TraceLevel.Off) { string traceLockPath = Path.Combine(env.TracePath, Constants.TraceLockFile); var traceLock = new LockFile(traceLockPath, NullTracerFactory.Instance, fileSystem); var tracer = new Tracer(Path.Combine(env.TracePath, Constants.TraceFile), level, traceLock); string logFile = System.Environment.GetEnvironmentVariable(Constants.TraceFileEnvKey); if (!String.IsNullOrEmpty(logFile)) { // Kudu.exe is executed as part of git.exe (post-receive), giving its initial depth of 4 indentations string logPath = Path.Combine(env.TracePath, logFile); return new CascadeTracer(tracer, new TextTracer(fileSystem, logPath, level, 4)); } return tracer; } return NullTracer.Instance; }
// key goal is to create background tracer that is independent of request. public static void PerformBackgroundDeployment(DeploymentInfo deployInfo, IEnvironment environment, IDeploymentSettingsManager settings, TraceLevel traceLevel, Uri uri, IDisposable tempDeployment, IAutoSwapHandler autoSwapHandler, ChangeSet tempChangeSet) { var tracer = traceLevel <= TraceLevel.Off ? NullTracer.Instance : new XmlTracer(environment.TracePath, traceLevel); var traceFactory = new TracerFactory(() => tracer); var backgroundTrace = tracer.Step(XmlTracer.BackgroundTrace, new Dictionary<string, string> { {"url", uri.AbsolutePath}, {"method", "POST"} }); Task.Run(() => { try { // lock related string lockPath = Path.Combine(environment.SiteRootPath, Constants.LockPath); string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile); string statusLockPath = Path.Combine(lockPath, Constants.StatusLockFile); string hooksLockPath = Path.Combine(lockPath, Constants.HooksLockFile); var statusLock = new LockFile(statusLockPath, traceFactory); var hooksLock = new LockFile(hooksLockPath, traceFactory); var deploymentLock = new DeploymentLockFile(deploymentLockPath, traceFactory); var analytics = new Analytics(settings, new ServerConfiguration(), traceFactory); var deploymentStatusManager = new DeploymentStatusManager(environment, analytics, statusLock); var repositoryFactory = new RepositoryFactory(environment, settings, traceFactory); var siteBuilderFactory = new SiteBuilderFactory(new BuildPropertyProvider(), environment); var webHooksManager = new WebHooksManager(tracer, environment, hooksLock); var functionManager = new FunctionManager(environment, traceFactory); var deploymentManager = new DeploymentManager(siteBuilderFactory, environment, traceFactory, analytics, settings, deploymentStatusManager, deploymentLock, NullLogger.Instance, webHooksManager, autoSwapHandler, functionManager); var fetchHandler = new FetchHandler(tracer, deploymentManager, settings, deploymentStatusManager, deploymentLock, environment, null, repositoryFactory, null); // Perform deployment var acquired = deploymentLock.TryLockOperation(() => { fetchHandler.PerformDeployment(deployInfo, tempDeployment, tempChangeSet).Wait(); }, TimeSpan.Zero); if (!acquired) { if (tempDeployment != null) { tempDeployment.Dispose(); } using (tracer.Step("Update pending deployment marker file")) { // REVIEW: This makes the assumption that the repository url is the same. // If it isn't the result would be buggy either way. FileSystemHelpers.SetLastWriteTimeUtc(fetchHandler._markerFilePath, DateTime.UtcNow); } } } catch (Exception ex) { tracer.TraceError(ex); } finally { backgroundTrace.Dispose(); } }); }
private static void TraceShutdown(IEnvironment environment, IKernel kernel) { TraceLevel level = kernel.Get<IDeploymentSettingsManager>().GetTraceLevel(); if (level > TraceLevel.Off) { string tracePath = Path.Combine(environment.TracePath, Constants.TraceFile); string traceLockPath = Path.Combine(environment.TracePath, Constants.TraceLockFile); var traceLock = new LockFile(traceLockPath); ITracer tracer = new Tracer(tracePath, level, traceLock); var attribs = new Dictionary<string, string>(); // Add an attribute containing the process, AppDomain and Thread ids to help debugging attribs.Add("pid", String.Format("{0},{1},{2}", Process.GetCurrentProcess().Id, AppDomain.CurrentDomain.Id.ToString(), System.Threading.Thread.CurrentThread.ManagedThreadId)); attribs.Add("uptime", TraceModule.UpTime.ToString()); attribs.Add("lastrequesttime", TraceModule.LastRequestTime.ToString()); tracer.Trace("Process Shutdown", attribs); } }
/// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { var serverConfiguration = new ServerConfiguration(); var gitConfiguration = new RepositoryConfiguration { Username = AppSettings.GitUsername, Email = AppSettings.GitEmail, TraceLevel = AppSettings.TraceLevel }; IEnvironment environment = GetEnvironment(); // General kernel.Bind<HttpContextBase>().ToMethod(context => new HttpContextWrapper(HttpContext.Current)); kernel.Bind<IEnvironment>().ToConstant(environment); kernel.Bind<IServerConfiguration>().ToConstant(serverConfiguration); kernel.Bind<IFileSystem>().To<FileSystem>().InSingletonScope(); kernel.Bind<RepositoryConfiguration>().ToConstant(gitConfiguration); string sdkPath = Path.Combine(HttpRuntime.AppDomainAppPath, SdkRootDirectory); kernel.Bind<IBuildPropertyProvider>().ToConstant(new BuildPropertyProvider()); if (AppSettings.TraceEnabled) { string tracePath = Path.Combine(environment.RootPath, Constants.TracePath, Constants.TraceFile); System.Func<ITracer> createTracerThunk = () => new Tracer(tracePath); // 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); } else { // Return No-op providers kernel.Bind<ITracer>().ToConstant(NullTracer.Instance).InSingletonScope(); kernel.Bind<ITraceFactory>().ToConstant(NullTracerFactory.Instance).InSingletonScope(); } // Setup the deployment lock string lockPath = Path.Combine(environment.SiteRootPath, Constants.LockPath); string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile); string sshKeyLockPath = Path.Combine(lockPath, Constants.SSHKeyLockFile); string initLockPath = Path.Combine(lockPath, Constants.InitLockFile); var deploymentLock = new LockFile(kernel.Get<ITraceFactory>(), deploymentLockPath); var initLock = new LockFile(kernel.Get<ITraceFactory>(), initLockPath); var sshKeyLock = new LockFile(kernel.Get<ITraceFactory>(), sshKeyLockPath); kernel.Bind<IOperationLock>().ToConstant(sshKeyLock).WhenInjectedInto<SSHKeyController>(); kernel.Bind<IOperationLock>().ToConstant(deploymentLock); // Setup the diagnostics service to collect information from the following paths: // 1. The deployments folder // 2. The profile dump // 3. The npm log var paths = new[] { environment.DeploymentCachePath, Path.Combine(environment.RootPath, Constants.LogFilesPath), Path.Combine(environment.WebRootPath, Constants.NpmDebugLogFile), }; kernel.Bind<DiagnosticsController>().ToMethod(context => new DiagnosticsController(paths)); // LogStream service kernel.Bind<LogStreamManager>().ToMethod(context => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath), context.Kernel.Get<ITracer>())); // Deployment Service kernel.Bind<ISettings>().ToMethod(context => new XmlSettings.Settings(GetSettingsPath(environment))); kernel.Bind<IDeploymentSettingsManager>().To<DeploymentSettingsManager>(); kernel.Bind<ISiteBuilderFactory>().To<SiteBuilderFactory>() .InRequestScope(); kernel.Bind<IServerRepository>().ToMethod(context => new GitExeServer(environment.RepositoryPath, initLock, context.Kernel.Get<IDeploymentEnvironment>(), context.Kernel.Get<ITraceFactory>())) .InRequestScope(); kernel.Bind<ILogger>().ToConstant(NullLogger.Instance); kernel.Bind<IDeploymentManager>().To<DeploymentManager>() .InRequestScope(); kernel.Bind<ISSHKeyManager>().To<SSHKeyManager>() .InRequestScope(); kernel.Bind<IDeploymentRepository>().ToMethod(context => new GitDeploymentRepository(environment.RepositoryPath, context.Kernel.Get<ITraceFactory>())) .InRequestScope(); // Git server kernel.Bind<IDeploymentEnvironment>().To<DeploymentEnvrionment>(); kernel.Bind<IGitServer>().ToMethod(context => new GitExeServer(environment.RepositoryPath, initLock, context.Kernel.Get<IDeploymentEnvironment>(), context.Kernel.Get<ITraceFactory>())) .InRequestScope(); // Editor kernel.Bind<IProjectSystem>().ToMethod(context => GetEditorProjectSystem(environment, context)) .InRequestScope(); // Command executor kernel.Bind<ICommandExecutor>().ToMethod(context => GetCommandExecutor(environment, context)) .InRequestScope(); RegisterRoutes(kernel, RouteTable.Routes); }
private static void RegisterServices(IKernel kernel) { var serverConfiguration = new ServerConfiguration(); // Make sure %HOME% is correctly set EnsureHomeEnvironmentVariable(); EnsureSiteBitnessEnvironmentVariable(); IEnvironment environment = GetEnvironment(); // 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>())) .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); var shutdownDetector = new ShutdownDetector(); shutdownDetector.Initialize(); IDeploymentSettingsManager noContextDeploymentsSettingsManager = new DeploymentSettingsManager(new XmlSettings.Settings(GetSettingsPath(environment))); var noContextTraceFactory = new TracerFactory(() => GetTracerWithoutContext(environment, noContextDeploymentsSettingsManager)); 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( 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>()); triggeredJobsManager.CleanupDeletedJobs(); continuousJobManager.CleanupDeletedJobs(); kernel.Bind<IContinuousJobsManager>().ToConstant(continuousJobManager) .InTransientScope(); TriggeredJobsScheduler triggeredJobsScheduler = new TriggeredJobsScheduler( triggeredJobsManager, noContextTraceFactory, environment); kernel.Bind<TriggeredJobsScheduler>().ToConstant(triggeredJobsScheduler) .InTransientScope(); kernel.Bind<ILogger>().ToMethod(context => GetLogger(environment, context.Kernel)) .InRequestScope(); kernel.Bind<IDeploymentManager>().To<DeploymentManager>() .InRequestScope(); kernel.Bind<IAutoSwapHandler>().To<AutoSwapHandler>() .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<CodingHandler>().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 OperationClient.SkipSslValidationIfNeeded(); // 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()); }
private static ITracer GetTracer(IEnvironment environment, IKernel kernel) { TraceLevel level = kernel.Get<IDeploymentSettingsManager>().GetTraceLevel(); if (level > TraceLevel.Off && TraceServices.CurrentRequestTraceFile != null) { string tracePath = Path.Combine(environment.TracePath, Constants.TraceFile); string textPath = Path.Combine(environment.TracePath, TraceServices.CurrentRequestTraceFile); string traceLockPath = Path.Combine(environment.TracePath, Constants.TraceLockFile); var traceLock = new LockFile(traceLockPath); return new CascadeTracer(new Tracer(tracePath, level, traceLock), new TextTracer(textPath, level)); } return NullTracer.Instance; }
private static ITracer GetTracerWithoutContext(IEnvironment environment, IDeploymentSettingsManager settings) { TraceLevel level = settings.GetTraceLevel(); if (level > TraceLevel.Off) { string tracePath = Path.Combine(environment.TracePath, Constants.TraceFile); string traceLockPath = Path.Combine(environment.TracePath, Constants.TraceLockFile); var traceLock = new LockFile(traceLockPath); return new Tracer(tracePath, level, traceLock); } return NullTracer.Instance; }
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"; 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); // 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; } }
/// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { var serverConfiguration = new ServerConfiguration(); var gitConfiguration = new RepositoryConfiguration { Username = AppSettings.GitUsername, Email = AppSettings.GitEmail }; IEnvironment environment = GetEnvironment(); var propertyProvider = new BuildPropertyProvider(); // General kernel.Bind<HttpContextBase>().ToMethod(context => new HttpContextWrapper(HttpContext.Current)); kernel.Bind<IBuildPropertyProvider>().ToConstant(propertyProvider); kernel.Bind<IEnvironment>().ToConstant(environment); kernel.Bind<IUserValidator>().To<SimpleUserValidator>().InSingletonScope(); kernel.Bind<IServerConfiguration>().ToConstant(serverConfiguration); kernel.Bind<IFileSystem>().To<FileSystem>().InSingletonScope(); kernel.Bind<RepositoryConfiguration>().ToConstant(gitConfiguration); if (AppSettings.TraceEnabled) { string tracePath = Path.Combine(environment.ApplicationRootPath, TracePath, TraceFile); System.Func<ITracer> createTracerThunk = () => new Tracer(tracePath); // 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); } else { // Return No-op providers kernel.Bind<ITracer>().ToConstant(NullTracer.Instance).InSingletonScope(); kernel.Bind<ITraceFactory>().ToConstant(NullTracerFactory.Instance).InSingletonScope(); } // Setup the deployment lock string lockPath = Path.Combine(environment.ApplicationRootPath, LockPath); string deploymentLockPath = Path.Combine(lockPath, DeploymentLockFile); string initLockPath = Path.Combine(lockPath, InitLockFile); var deploymentLock = new LockFile(kernel.Get<ITraceFactory>(), deploymentLockPath); var initLock = new LockFile(kernel.Get<ITraceFactory>(), initLockPath); kernel.Bind<IOperationLock>().ToConstant(deploymentLock); // Setup the diagnostics service to collect information from the following paths: // 1. The deployments folder // 2. The elmah error log // 3. The profile dump var paths = new[] { environment.DeploymentCachePath, Path.Combine(environment.ApplicationRootPath, TracePath), }; kernel.Bind<DiagnosticsService>().ToMethod(context => new DiagnosticsService(paths)); // Deployment Service kernel.Bind<ISettings>().ToMethod(context => new XmlSettings.Settings(GetSettingsPath(environment))); kernel.Bind<IDeploymentSettingsManager>().To<DeploymentSettingsManager>(); kernel.Bind<ISiteBuilderFactory>().To<SiteBuilderFactory>() .InRequestScope(); kernel.Bind<IServerRepository>().ToMethod(context => new GitExeServer(environment.DeploymentRepositoryPath, initLock, context.Kernel.Get<ITraceFactory>())) .InRequestScope(); kernel.Bind<IDeploymentManager>().To<DeploymentManager>() .InRequestScope() .OnActivation(SubscribeForDeploymentEvents); // Git server kernel.Bind<IDeploymentManagerFactory>().ToMethod(context => GetDeploymentManagerFactory(environment, initLock, deploymentLock, propertyProvider, context.Kernel.Get<ITraceFactory>())); kernel.Bind<IGitServer>().ToMethod(context => new GitExeServer(environment.DeploymentRepositoryPath, initLock, context.Kernel.Get<ITraceFactory>())) .InRequestScope(); // Hg Server kernel.Bind<IHgServer>().To<Kudu.Core.SourceControl.Hg.HgServer>() .InSingletonScope(); // Editor kernel.Bind<IProjectSystem>().ToMethod(context => GetEditorProjectSystem(environment, context)) .InRequestScope(); // Command line //kernel.Bind<ICommandExecutor>().ToMethod(context => GetComandExecutor(environment, context)) // .InRequestScope(); // Source control // kernel.Bind<IRepository>().ToMethod(context => GetSourceControlRepository(environment)); //kernel.Bind<IClonableRepository>().ToMethod(context => (IClonableRepository)GetDevelopmentRepositoryManager(environment)); }
public AsyncLockFileTests() { _lockFilePath = Path.Combine(PathHelper.TestLockPath, "file.lock"); _lockFile = new LockFile(_lockFilePath, NullTracerFactory.Instance, new FileSystem()); _lockFile.InitializeAsyncLocks(); }
static int Main(string[] args) { if (args.Length < 2) { System.Console.WriteLine("Usage: kudu.exe {appRoot} {wapTargets}"); 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 nugetCachePath = null; IEnvironment env = GetEnvironment(appRoot, nugetCachePath); // Setup the trace string tracePath = Path.Combine(env.ApplicationRootPath, Constants.TracePath, Constants.TraceFile); var tracer = new Tracer(tracePath); var traceFactory = new TracerFactory(() => tracer); // Calculate the lock path string lockPath = Path.Combine(env.ApplicationRootPath, Constants.LockPath); string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile); var deploymentLock = new LockFile(traceFactory, deploymentLockPath); var fs = new FileSystem(); var buildPropertyProvider = new BuildPropertyProvider(wapTargets); var builderFactory = new SiteBuilderFactory(buildPropertyProvider, env); var serverRepository = new GitDeploymentRepository(env.DeploymentRepositoryPath, traceFactory); var logger = new ConsoleLogger(); var deploymentManager = new DeploymentManager(serverRepository, builderFactory, env, fs, traceFactory, deploymentLock, 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(); } catch (System.Exception ex) { System.Console.Error.WriteLine(ex.Message); System.Console.Error.WriteLine(Resources.Log_DeploymentError); tracer.TraceError(ex); throw; } } if (logger.HasErrors) { System.Console.Error.WriteLine(Resources.Log_DeploymentError); return 1; } return 0; }
public JsonSettings(string path) { _path = path; _lock = new LockFile(string.Format(CultureInfo.InvariantCulture, "{0}.lock", path)); }
public TriggeredJobRunner(string jobName, IEnvironment environment, IFileSystem fileSystem, IDeploymentSettingsManager settings, ITraceFactory traceFactory, IAnalytics analytics) : base(jobName, Constants.TriggeredPath, environment, fileSystem, settings, traceFactory, analytics) { _lockFile = new LockFile(Path.Combine(JobDataPath, "triggeredJob.lock"), TraceFactory, FileSystem); }
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); // Setup the trace string tracePath = Path.Combine(env.RootPath, Constants.TracePath, Constants.TraceFile); var tracer = new Tracer(tracePath); 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 builderFactory = new SiteBuilderFactory(buildPropertyProvider, env); var serverRepository = new GitDeploymentRepository(env.RepositoryPath, traceFactory); var settings = new XmlSettings.Settings(GetSettingsPath(env)); var settingsManager = new DeploymentSettingsManager(settings); var logger = new ConsoleLogger(); var deploymentManager = new DeploymentManager(serverRepository, builderFactory, env, fs, traceFactory, settingsManager, deploymentLock, 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; }
public async Task AsyncLock_ThrowsIfNotInitialized() { string lockFilePath = Path.Combine(PathHelper.TestLockPath, "uninitialized.lock"); LockFile uninitialized = new LockFile(lockFilePath, NullTracerFactory.Instance); await Assert.ThrowsAsync<InvalidOperationException>(() => uninitialized.LockAsync("operationName")); }
public void AsyncLock_ThrowsIfNotInitialized() { string lockFilePath = Path.Combine(PathHelper.TestLockPath, "uninitialized.lock"); LockFile uninitialized = new LockFile(lockFilePath, NullTracerFactory.Instance, new FileSystem()); Assert.Throws<InvalidOperationException>(() => uninitialized.LockAsync()); }
public TriggeredJobRunner(string jobName, IEnvironment environment, IDeploymentSettingsManager settings, ITraceFactory traceFactory, IAnalytics analytics) : base(jobName, Constants.TriggeredPath, environment, settings, traceFactory, analytics) { _lockFile = BuildTriggeredJobRunnerLockFile(JobDataPath, TraceFactory); }
private static void RegisterServices(IKernel kernel) { var serverConfiguration = new ServerConfiguration(); 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)); kernel.Bind<IServerConfiguration>().ToConstant(serverConfiguration); kernel.Bind<IFileSystem>().To<FileSystem>().InSingletonScope(); 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); var fileSystem = new FileSystem(); var deploymentLock = new LockFile(deploymentLockPath, kernel.Get<ITraceFactory>(), fileSystem); var statusLock = new LockFile(statusLockPath, kernel.Get<ITraceFactory>(), fileSystem); var sshKeyLock = new LockFile(sshKeyLockPath, kernel.Get<ITraceFactory>(), fileSystem); kernel.Bind<IOperationLock>().ToConstant(sshKeyLock).WhenInjectedInto<SSHKeyController>(); kernel.Bind<IOperationLock>().ToConstant(statusLock).WhenInjectedInto<DeploymentStatusManager>(); kernel.Bind<IOperationLock>().ToConstant(deploymentLock); var shutdownDetector = new ShutdownDetector(); shutdownDetector.Initialize(); // Trace shutdown event // Cannot use shutdownDetector.Token.Register because of race condition // with NinjectServices.Stop via WebActivator.ApplicationShutdownMethodAttribute Shutdown += () => TraceShutdown(environment, kernel); // LogStream service 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)); 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<SiteBuilderFactoryDispatcher>() .InRequestScope(); 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>().To<RepositoryFactory>() .InRequestScope(); // 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(); // Command executor kernel.Bind<ICommandExecutor>().ToMethod(context => GetCommandExecutor(environment, context)) .InRequestScope(); RegisterRoutes(kernel, RouteTable.Routes); }
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); 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 IFileSystem fileSystem = new FileSystem(); TraceLevel level = settingsManager.GetTraceLevel(); ITracer tracer = GetTracer(env, level, fileSystem); 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); IOperationLock deploymentLock = new LockFile(deploymentLockPath, traceFactory, fileSystem); IOperationLock statusLock = new LockFile(statusLockPath, traceFactory, fileSystem); IBuildPropertyProvider buildPropertyProvider = new BuildPropertyProvider(); ISiteBuilderFactory builderFactory = new SiteBuilderFactory(buildPropertyProvider, env); IRepository gitRepository = new GitExeRepository(env, settingsManager, traceFactory); var logger = new ConsoleLogger(); IDeploymentManager deploymentManager = new DeploymentManager(builderFactory, env, fileSystem, traceFactory, settingsManager, new DeploymentStatusManager(env, fileSystem, statusLock), 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(gitRepository, changeSet: null, deployer: deployer, clean: false); } catch (Exception e) { System.Console.Error.WriteLine(e.Message); System.Console.Error.WriteLine(Resources.Log_DeploymentError); return 1; } } if (logger.HasErrors) { System.Console.Error.WriteLine(Resources.Log_DeploymentError); return 1; } return 0; }
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); // Temporary fix for https://github.com/npm/npm/issues/5905 EnsureNpmGlobalDirectory(); RegisterRoutes(kernel, RouteTable.Routes); // Register the default hubs route: ~/signalr GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(kernel); RouteTable.Routes.MapConnection<PersistentCommandController>("commandstream", "/api/commandstream"); RouteTable.Routes.MapHubs("/api/filesystemhub", new HubConfiguration()); }
private static int PerformDeploy( string appRoot, string wapTargets, string deployer, string lockPath, IEnvironment env, IDeploymentSettingsManager settingsManager, TraceLevel level, ITracer tracer, ITraceFactory traceFactory, IOperationLock deploymentLock) { System.Environment.SetEnvironmentVariable("GIT_DIR", null, System.EnvironmentVariableTarget.Process); // Skip SSL Certificate Validate OperationClient.SkipSslValidationIfNeeded(); // Adjust repo path env.RepositoryPath = Path.Combine(env.SiteRootPath, settingsManager.GetRepositoryPath()); string statusLockPath = Path.Combine(lockPath, Constants.StatusLockFile); string hooksLockPath = Path.Combine(lockPath, Constants.HooksLockFile); IOperationLock statusLock = new LockFile(statusLockPath, traceFactory); IOperationLock hooksLock = new LockFile(hooksLockPath, traceFactory); IBuildPropertyProvider buildPropertyProvider = new BuildPropertyProvider(); ISiteBuilderFactory builderFactory = new SiteBuilderFactory(buildPropertyProvider, env); var logger = new ConsoleLogger(); 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(env, settingsManager, traceFactory); var functionManager = new FunctionManager(env, traceFactory); IDeploymentManager deploymentManager = new DeploymentManager(builderFactory, env, traceFactory, analytics, settingsManager, deploymentStatusManager, deploymentLock, GetLogger(env, level, logger), hooksManager, 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(); string branch = settingsManager.GetBranch(); ChangeSet changeSet = gitRepository.GetChangeSet(branch); IDeploymentStatusFile statusFile = deploymentStatusManager.Open(changeSet.Id); if (statusFile != null && statusFile.Status == DeployStatus.Success) { autoSwapHander.HandleAutoSwap(changeSet.Id, deploymentManager.GetLogger(changeSet.Id), tracer).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; }
/// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { var serverConfiguration = new ServerConfiguration(); var gitConfiguration = new RepositoryConfiguration { Username = AppSettings.GitUsername, Email = AppSettings.GitEmail }; IEnvironment environment = GetEnvironment(); // General kernel.Bind<HttpContextBase>().ToMethod(context => new HttpContextWrapper(HttpContext.Current)); kernel.Bind<IEnvironment>().ToConstant(environment); kernel.Bind<IServerConfiguration>().ToConstant(serverConfiguration); kernel.Bind<IFileSystem>().To<FileSystem>().InSingletonScope(); kernel.Bind<RepositoryConfiguration>().ToConstant(gitConfiguration); string sdkPath = Path.Combine(HttpRuntime.AppDomainAppPath, SdkRootDirectory); 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 sshKeyLockPath = Path.Combine(lockPath, Constants.SSHKeyLockFile); string initLockPath = Path.Combine(lockPath, Constants.InitLockFile); var deploymentLock = new LockFile(kernel.Get<ITraceFactory>(), deploymentLockPath); var initLock = new LockFile(kernel.Get<ITraceFactory>(), initLockPath); var sshKeyLock = new LockFile(kernel.Get<ITraceFactory>(), sshKeyLockPath); kernel.Bind<IOperationLock>().ToConstant(sshKeyLock).WhenInjectedInto<SSHKeyController>(); kernel.Bind<IOperationLock>().ToConstant(deploymentLock); var shutdownDetector = new ShutdownDetector(); shutdownDetector.Initialize(); // LogStream service kernel.Bind<LogStreamManager>().ToMethod(context => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath), context.Kernel.Get<ITracer>(), shutdownDetector)); // Deployment Service kernel.Bind<ISettings>().ToMethod(context => new XmlSettings.Settings(GetSettingsPath(environment))) .InRequestScope(); kernel.Bind<IDeploymentSettingsManager>().To<DeploymentSettingsManager>() .InRequestScope(); kernel.Bind<ISiteBuilderFactory>().To<SiteBuilderFactoryDispatcher>() .InRequestScope(); kernel.Bind<IServerRepository>().ToMethod(context => new GitExeServer(environment.RepositoryPath, environment.SiteRootPath, initLock, GetRequestTraceFile(environment, context.Kernel), context.Kernel.Get<IDeploymentEnvironment>(), context.Kernel.Get<ITraceFactory>())) .InRequestScope(); kernel.Bind<ILogger>().ToMethod(context => GetLogger(environment, context.Kernel)) .InRequestScope(); kernel.Bind<IRepository>().ToMethod(context => new GitExeRepository(environment.RepositoryPath, environment.SiteRootPath, context.Kernel.Get<ITraceFactory>())) .InRequestScope(); kernel.Bind<IDeploymentManager>().To<DeploymentManager>() .InRequestScope(); kernel.Bind<ISSHKeyManager>().To<SSHKeyManager>() .InRequestScope(); kernel.Bind<IDeploymentRepository>().ToMethod(context => new GitDeploymentRepository(environment.RepositoryPath, environment.SiteRootPath, context.Kernel.Get<ITraceFactory>())) .InRequestScope(); // Git server kernel.Bind<IDeploymentEnvironment>().To<DeploymentEnvrionment>(); kernel.Bind<IGitServer>().ToMethod(context => new GitExeServer(environment.RepositoryPath, environment.SiteRootPath, initLock, GetRequestTraceFile(environment, context.Kernel), context.Kernel.Get<IDeploymentEnvironment>(), context.Kernel.Get<ITraceFactory>())) .InRequestScope(); // Git Servicehook parsers 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(); // Command executor kernel.Bind<ICommandExecutor>().ToMethod(context => GetCommandExecutor(environment, context)) .InRequestScope(); RegisterRoutes(kernel, RouteTable.Routes); }