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; }
// 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(); } }); }
public static void UnexpectedException(Exception ex, ITraceFactory traceFactory) { var analytic = new Analytics(null, new ServerConfiguration(), traceFactory); analytic.UnexpectedException(ex, trace: true); }
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 (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 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); string analyticsPath = env.AnalyticsPath; 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 = new GitExeRepository(env, settingsManager, traceFactory); IAnalytics analytics = new Analytics(settingsManager, tracer, analyticsPath); IWebHooksManager hooksManager = new WebHooksManager(tracer, env, hooksLock); var logger = new ConsoleLogger(); IDeploymentManager deploymentManager = new DeploymentManager(builderFactory, env, traceFactory, analytics, settingsManager, new DeploymentStatusManager(env, statusLock), deploymentLock, GetLogger(env, level, logger), hooksManager); var step = tracer.Step("Executing external process", 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; }