private void PreDeployment(ITracer tracer) { if (Environment.IsAzureEnvironment() && FileSystemHelpers.DirectoryExists(_environment.SSHKeyPath) && OSDetector.IsOnWindows()) { string src = Path.GetFullPath(_environment.SSHKeyPath); string dst = Path.GetFullPath(Path.Combine(System.Environment.GetEnvironmentVariable("USERPROFILE"), Constants.SSHKeyPath)); if (!String.Equals(src, dst, StringComparison.OrdinalIgnoreCase)) { // copy %HOME%\.ssh to %USERPROFILE%\.ssh key to workaround // npm with private ssh git dependency using (tracer.Step("Copying SSH keys")) { FileSystemHelpers.CopyDirectoryRecursive(src, dst, overwrite: true); } } } }
public Environment( string rootPath, string binPath, string repositoryPath) { RootPath = rootPath; SiteRootPath = Path.Combine(rootPath, Constants.SiteFolder); _tempPath = Path.GetTempPath(); _repositoryPath = repositoryPath; _webRootPath = Path.Combine(SiteRootPath, Constants.WebRoot); _deploymentsPath = Path.Combine(SiteRootPath, Constants.DeploymentCachePath); _deploymentToolsPath = Path.Combine(_deploymentsPath, Constants.DeploymentToolsPath); _siteExtensionSettingsPath = Path.Combine(SiteRootPath, Constants.SiteExtensionsCachePath); _diagnosticsPath = Path.Combine(SiteRootPath, Constants.DiagnosticsPath); _locksPath = Path.Combine(SiteRootPath, Constants.LocksPath); if (OSDetector.IsOnWindows()) { _sshKeyPath = Path.Combine(rootPath, Constants.SSHKeyPath); } else { // in linux, rootPath is "/home", while .ssh folder need to under "/home/{user}", // and username and site name is always the same in actual deployment string siteName = System.Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); siteName = NormalizeSiteName(siteName); _sshKeyPath = Path.Combine(rootPath, siteName, Constants.SSHKeyPath); } _scriptPath = Path.Combine(binPath, Constants.ScriptsPath); _nodeModulesPath = Path.Combine(binPath, Constants.NodeModulesPath); _logFilesPath = Path.Combine(rootPath, Constants.LogFilesPath); _applicationLogFilesPath = Path.Combine(_logFilesPath, Constants.ApplicationLogFilesDirectory); _tracePath = Path.Combine(rootPath, Constants.TracePath); _analyticsPath = Path.Combine(_tempPath ?? _logFilesPath, Constants.SiteExtensionLogsDirectory); _deploymentTracePath = Path.Combine(rootPath, Constants.DeploymentTracePath); _dataPath = Path.Combine(rootPath, Constants.DataPath); _jobsDataPath = Path.Combine(_dataPath, Constants.JobsPath); _jobsBinariesPath = Path.Combine(_webRootPath, Constants.AppDataPath, Constants.JobsPath); }
public override Task Build(DeploymentContext context) { var tcs = new TaskCompletionSource <object>(); context.Logger.Log("Running custom deployment command..."); var commandFullPath = _command; try { if (!OSDetector.IsOnWindows()) { if (commandFullPath.StartsWith(".")) { string finalCommandPath = Path.GetFullPath(Path.Combine(RepositoryPath, commandFullPath)); if (File.Exists(finalCommandPath)) { commandFullPath = finalCommandPath; } } if (commandFullPath.Contains(RepositoryPath)) { context.Logger.Log("Setting execute permissions for " + commandFullPath); PermissionHelper.Chmod("ugo+x", commandFullPath, Environment, DeploymentSettings, context.Logger); } else { context.Logger.Log("Not setting execute permissions for " + commandFullPath); } } RunCommand(context, _command, ignoreManifest: false); tcs.SetResult(null); } catch (Exception ex) { tcs.SetException(ex); } return(tcs.Task); }
public static void Start() { if (!Kudu.Core.Environment.IsAzureEnvironment() || !OSDetector.IsOnWindows()) { return; } if (Interlocked.Exchange(ref _running, 1) != 0) { return; } // Cleanup Sentinel on Startup OperationManager.SafeExecute(() => { FileSystemHelpers.DeleteDirectorySafe(Path.Combine(PathUtilityFactory.Instance.ResolveLocalSitePath(), @"ShutdownSentinel")); }); ThreadPool.QueueUserWorkItem(BackgroundTaskProc, new ManualResetEvent(initialState: false)); }
/// <summary> /// Ensures %HOME% is correctly set /// </summary> internal static void EnsureHomeEnvironmentVariable() { // PlatformServices.Default and the injected IHostingEnvironment have at runtime. if (Directory.Exists(System.Environment.ExpandEnvironmentVariables(@"%HOME%"))) { return; } //For Debug System.Environment.SetEnvironmentVariable("HOME", OSDetector.IsOnWindows() ? @"F:\kudu-debug" : "/home"); /* * // If MapPath("/_app") returns a valid folder, set %HOME% to that, regardless of * // it current value. This is the non-Azure code path. * string path = HostingEnvironment.MapPath(Constants.MappedSite); * if (Directory.Exists(path)) * { * path = Path.GetFullPath(path); * System.Environment.SetEnvironmentVariable("HOME", path); * } */ }
public static NodeOSInfo GetHostInfo(string nodeIP) { NodeOSInfo nodeInfo; if (s_hostInfoMap.TryGetValue(nodeIP, out nodeInfo)) { return(s_hostInfoMap[nodeIP]); } else { OSInfo osInfo = OSDetector.DetectOS(nodeIP); if (OSDetector.hostIP == null) { return(null); } nodeIP = OSDetector.hostIP; if (osInfo == OSInfo.Unix) { nodeInfo = new NodeOSInfo(nodeIP, OSInfo.Unix); AddHostInfo(nodeIP, nodeInfo); return(nodeInfo); } else if (osInfo == OSInfo.Windows) { nodeInfo = new NodeOSInfo(nodeIP, OSInfo.Windows); AddHostInfo(nodeIP, nodeInfo); return(nodeInfo); } else { nodeInfo = new NodeOSInfo(nodeIP, OSInfo.Unknown); AddHostInfo(nodeIP, nodeInfo); return(nodeInfo); } } }
/// <summary> /// Get parent process. /// </summary> public static Process GetParentProcess(this Process process, ITracer tracer) { if (!OSDetector.IsOnWindows()) { return(process.GetParentProcessLinux(tracer)); } IntPtr processHandle; if (!process.TryGetProcessHandle(out processHandle)) { return(null); } var pbi = new ProcessNativeMethods.ProcessInformation(); try { int returnLength; int status = ProcessNativeMethods.NtQueryInformationProcess(processHandle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); if (status != 0) { throw new Win32Exception(status); } return(Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32())); } catch (Exception ex) { var processName = process.SafeGetProcessName() ?? "(null)"; if (!processName.Equals("w3wp", StringComparison.OrdinalIgnoreCase)) { tracer.TraceError(ex, "GetParentProcess of {0}({1}) failed.", processName, process.Id); } return(null); } }
public void PostBuild(DeploymentContext context) { context.Logger.Log("Running post deployment command(s)..."); foreach (var file in GetPostBuildActionScripts()) { var fi = new FileInfo(file); string scriptFilePath = null; if (OSDetector.IsOnWindows()) { scriptFilePath = GetWindowsPostBuildFilepath(context, fi); } else if (!OSDetector.IsOnWindows()) { scriptFilePath = GetLinuxPostBuildFilepath(context, fi); } if (string.IsNullOrEmpty(scriptFilePath)) { scriptFilePath = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", file); } RunCommand(context, scriptFilePath, false, Path.GetFileNameWithoutExtension(file)); } }
public static Uri GetRequestUri(HttpRequestMessage request) { var uri = request.RequestUri; // On Linux, corrections to the request URI are needed due to the way the request is handled on the worker: // - Set scheme to https // - Set host to the value of DISGUISED-HOST // - Remove port value IEnumerable <string> disguisedHostValues; if (!OSDetector.IsOnWindows() && request.Headers.TryGetValues("DISGUISED-HOST", out disguisedHostValues) && disguisedHostValues.Count() > 0) { uri = (new UriBuilder(uri) { Scheme = "https", Host = disguisedHostValues.First(), Port = -1 }).Uri; } return(uri); }
public void Initialize() { var tracer = _tracerFactory.GetTracer(); using (tracer.Step("GitExeRepository.Initialize")) { Execute(tracer, "init"); Execute(tracer, "config core.autocrlf {0}", OSDetector.IsOnWindows() ? "true" : "false"); // This speeds up git operations like 'git checkout', especially on slow drives like in Azure Execute(tracer, "config core.preloadindex true"); Execute(tracer, @"config user.name ""{0}""", _settings.GetGitUsername()); Execute(tracer, @"config user.email ""{0}""", _settings.GetGitEmail()); // This is needed to make lfs work Execute(tracer, @"config filter.lfs.clean ""git-lfs clean %f"""); Execute(tracer, @"config filter.lfs.smudge ""git-lfs smudge %f"""); Execute(tracer, @"config filter.lfs.required true"); using (tracer.Step("Configure git server")) { // Allow getting pushes even though we're not bare Execute(tracer, "config receive.denyCurrentBranch ignore"); } // to disallow browsing to this folder in case of in-place repo using (tracer.Step("Create deny users for .git folder")) { string content = "<?xml version=\"1.0\"" + @"?> <configuration> <system.web> <authorization> <deny users=" + "\"*\"" + @"/> </authorization> </system.web> <configuration>"; File.WriteAllText(Path.Combine(_gitExe.WorkingDirectory, ".git", "web.config"), content); } // Server env does not support interactive cred prompt; hence, we intercept any credential provision // for git fetch/clone with http/https scheme and return random invalid u/p forcing 'fatal: Authentication failed.' using (tracer.Step("Configure git-credential")) { FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(GitCredentialHookPath)); string content = @"#!/bin/sh if [ " + "\"$1\" = \"get\"" + @" ]; then echo username=dummyUser echo password=dummyPassword fi" + "\n"; File.WriteAllText(GitCredentialHookPath, content); Execute(tracer, "config credential.helper \"!'{0}'\"", GitCredentialHookPath); } using (tracer.Step("Setup post receive hook")) { FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(PostReceiveHookPath)); //#!/bin/sh //read i //echo $i > pushinfo //KnownEnvironment.KUDUCOMMAND StringBuilder sb = new StringBuilder(); sb.AppendLine("#!/bin/sh"); sb.AppendLine("read i"); sb.AppendLine("echo $i > pushinfo"); sb.AppendLine(KnownEnvironment.KUDUCOMMAND); if (OSDetector.IsOnWindows()) { FileSystemHelpers.WriteAllText(PostReceiveHookPath, sb.ToString()); } else { FileSystemHelpers.WriteAllText(PostReceiveHookPath, sb.ToString().Replace("\r\n", "\n")); using (tracer.Step("Non-Windows enviroment, granting 755 permission to post-receive hook file")) { PermissionHelper.Chmod("755", PostReceiveHookPath, _environment, _settings, NullLogger.Instance); } } } // NOTE: don't add any new init steps after creating the post receive hook, // as it's also used to mark that Init was fully executed } }
public Environment( string rootPath, string binPath, string repositoryPath, string requestId, string kuduConsoleFullPath, IHttpContextAccessor httpContextAccessor) { RootPath = rootPath; SiteRootPath = Path.Combine(rootPath, Constants.SiteFolder); _tempPath = Path.GetTempPath(); _repositoryPath = repositoryPath; _zipTempPath = Path.Combine(_tempPath, Constants.ZipTempPath); _webRootPath = Path.Combine(SiteRootPath, Constants.WebRoot); _deploymentsPath = Path.Combine(SiteRootPath, Constants.DeploymentCachePath); _deploymentToolsPath = Path.Combine(_deploymentsPath, Constants.DeploymentToolsPath); _siteExtensionSettingsPath = Path.Combine(SiteRootPath, Constants.SiteExtensionsCachePath); _diagnosticsPath = Path.Combine(SiteRootPath, Constants.DiagnosticsPath); _locksPath = Path.Combine(SiteRootPath, Constants.LocksPath); if (OSDetector.IsOnWindows()) { _sshKeyPath = Path.Combine(rootPath, Constants.SSHKeyPath); } else { // in linux, rootPath is "/home", while .ssh folder need to under "/home/{user}" _sshKeyPath = Path.Combine(rootPath, System.Environment.GetEnvironmentVariable("KUDU_RUN_USER"), Constants.SSHKeyPath); } _scriptPath = Path.Combine(binPath, Constants.ScriptsPath); _nodeModulesPath = Path.Combine(binPath, Constants.NodeModulesPath); _logFilesPath = Path.Combine(rootPath, Constants.LogFilesPath); _applicationLogFilesPath = Path.Combine(_logFilesPath, Constants.ApplicationLogFilesDirectory); _tracePath = Path.Combine(rootPath, Constants.TracePath); _analyticsPath = Path.Combine(_tempPath ?? _logFilesPath, Constants.SiteExtensionLogsDirectory); _deploymentTracePath = Path.Combine(rootPath, Constants.DeploymentTracePath); _dataPath = Path.Combine(rootPath, Constants.DataPath); _jobsDataPath = Path.Combine(_dataPath, Constants.JobsPath); _jobsBinariesPath = Path.Combine(_webRootPath, Constants.AppDataPath, Constants.JobsPath); _secondaryJobsBinariesPath = Path.Combine(SiteRootPath, Constants.JobsPath); string userDefinedWebJobRoot = System.Environment.GetEnvironmentVariable(SettingsKeys.WebJobsRootPath); if (!String.IsNullOrEmpty(userDefinedWebJobRoot)) { userDefinedWebJobRoot = System.Environment.ExpandEnvironmentVariables(userDefinedWebJobRoot).Trim('\\', '/'); // Path.Combine(p1,p2) returns p2 if p2 is an absolute path // default _jobsBinariesPath = "D:/home/site/wwwroot/App_Data/jobs" // if userDefinedWebJobRoot = "myfunctions", _jobsBinariesPath = "D:/home/site/wwwroot/myfunctions" // if userDefinedWebJobRoot = "D:/home/functionfolder", _jobsBinariesPath = "D:/home/functionfolder" _jobsBinariesPath = Path.Combine(_webRootPath, userDefinedWebJobRoot); } _sitePackagesPath = Path.Combine(_dataPath, Constants.SitePackages); RequestId = !string.IsNullOrEmpty(requestId) ? requestId : Guid.Empty.ToString(); _httpContextAccessor = httpContextAccessor; KuduConsoleFullPath = kuduConsoleFullPath; }
public async Task DeployAsync(IRepository repository, ChangeSet changeSet, string deployer, bool clean, bool needFileUpdate = true) { using (var deploymentAnalytics = new DeploymentAnalytics(_analytics, _settings)) { Exception exception = null; ITracer tracer = _traceFactory.GetTracer(); IDisposable deployStep = null; ILogger innerLogger = null; string targetBranch = null; // If we don't get a changeset, find out what branch we should be deploying and get the commit ID from it if (changeSet == null) { targetBranch = _settings.GetBranch(); changeSet = repository.GetChangeSet(targetBranch); if (changeSet == null) { throw new InvalidOperationException(String.Format("The current deployment branch is '{0}', but nothing has been pushed to it", targetBranch)); } } string id = changeSet.Id; IDeploymentStatusFile statusFile = null; try { deployStep = tracer.Step($"DeploymentManager.Deploy(id:{id})"); // Remove the old log file for this deployment id string logPath = GetLogPath(id); FileSystemHelpers.DeleteFileSafe(logPath); statusFile = GetOrCreateStatusFile(changeSet, tracer, deployer); statusFile.MarkPending(); ILogger logger = GetLogger(changeSet.Id); if (needFileUpdate) { using (tracer.Step("Updating to specific changeset")) { innerLogger = logger.Log(Resources.Log_UpdatingBranch, targetBranch ?? id); using (var writer = new ProgressWriter()) { // Update to the specific changeset or branch repository.Update(targetBranch ?? id); } } } if (_settings.ShouldUpdateSubmodules()) { using (tracer.Step("Updating submodules")) { innerLogger = logger.Log(Resources.Log_UpdatingSubmodules); repository.UpdateSubmodules(); } } if (clean) { tracer.Trace("Cleaning {0} repository", repository.RepositoryType); innerLogger = logger.Log(Resources.Log_CleaningRepository, repository.RepositoryType); repository.Clean(); } // set to null as Build() below takes over logging innerLogger = null; // Perform the build deployment of this changeset await Build(changeSet, tracer, deployStep, repository, deploymentAnalytics); if (!OSDetector.IsOnWindows() && _settings.RestartAppContainerOnGitDeploy()) { logger.Log(Resources.Log_TriggeringContainerRestart); LinuxContainerRestartTrigger.RequestContainerRestart(_environment, RestartTriggerReason); } } catch (Exception ex) { exception = ex; if (innerLogger != null) { innerLogger.Log(ex); } if (statusFile != null) { MarkStatusComplete(statusFile, success: false); } tracer.TraceError(ex); deploymentAnalytics.Error = ex.ToString(); if (deployStep != null) { deployStep.Dispose(); } } // Reload status file with latest updates statusFile = _status.Open(id); if (statusFile != null) { await _hooksManager.PublishEventAsync(HookEventTypes.PostDeployment, statusFile); } if (exception != null) { throw new DeploymentFailedException(exception); } } }
public static string GetStartupFileName() { return(OSDetector.IsOnWindows() ? "startup.cmd" : "startup.sh"); }
public static void Extract(this ZipArchive archive, string directoryName) { foreach (ZipArchiveEntry entry in archive.Entries) { string path = Path.Combine(directoryName, entry.FullName); if (entry.Length == 0 && (path.EndsWith("/", StringComparison.Ordinal) || path.EndsWith("\\", StringComparison.Ordinal))) { // Extract directory FileSystemHelpers.CreateDirectory(path); } else { FileInfoBase fileInfo = FileSystemHelpers.FileInfoFromFileName(path); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } using (Stream zipStream = entry.Open(), fileStream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { zipStream.CopyTo(fileStream); } bool createSymLink = false; string originalFileName = string.Empty; if (!OSDetector.IsOnWindows()) { try { using (Stream fs = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { byte[] buffer = new byte[10]; fs.Read(buffer, 0, buffer.Length); fs.Close(); var str = System.Text.Encoding.Default.GetString(buffer); if (str.StartsWith("../")) { string fullPath = Path.GetFullPath(str); if (fullPath.StartsWith(directoryName)) { createSymLink = true; originalFileName = fullPath; } } } } catch (Exception ex) { throw new Exception("Could not identify symlinks in zip file : " + ex.ToString()); } } fileInfo.LastWriteTimeUtc = entry.LastWriteTime.ToUniversalTime().DateTime; if (createSymLink) { try { fileInfo.Delete(); Mono.Unix.UnixFileInfo unixFileInfo = new Mono.Unix.UnixFileInfo(originalFileName); unixFileInfo.CreateSymbolicLink(path); } catch (Exception ex) { throw new Exception("Could not create symlinks : " + ex.ToString()); } } } } }
public bool Acquire(ITracer tracer) { lock (_lock) { try { // No timeout makes this call instant. No waiting for acquistion bool acquired = _shutdownSemaphore.Wait(millisecondsTimeout: 0); if (!acquired) { tracer.Trace("Could not acquire shutdown semaphore", new Dictionary <string, string> { { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } }); return(false); } //tracer.Trace("Acquired shutdown semaphore", new Dictionary<string, string> //{ // { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } //}); OperationManager.SafeExecute(() => { if (Environment.IsAzureEnvironment() && OSDetector.IsOnWindows()) { string siteRoot = PathUtilityFactory.Instance.ResolveLocalSitePath(); // Create Sentinel file for DWAS to check // DWAS will check for presence of this file incase a an app setting based recycle needs to be performed in middle of deployment // If this is present, DWAS will postpone the recycle so that deployment goes through first if (!string.IsNullOrEmpty(siteRoot)) { FileSystemHelpers.CreateDirectory(Path.Combine(siteRoot, @"ShutdownSentinel")); string sentinelPath = Path.Combine(siteRoot, @"ShutdownSentinel\Sentinel.txt"); if (!FileSystemHelpers.FileExists(sentinelPath)) { //tracer.Trace("Creating shutdown sentinel file", new Dictionary<string, string> //{ // { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } //}); var file = FileSystemHelpers.CreateFile(sentinelPath); file.Close(); } tracer.Trace("Updating shutdown sentinel last write time", new Dictionary <string, string> { { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } }); // DWAS checks if write time of this file is in the future then only postpones the recycle FileInfoBase sentinelFileInfo = FileSystemHelpers.FileInfoFromFileName(sentinelPath); sentinelFileInfo.LastWriteTimeUtc = DateTime.UtcNow.AddMinutes(20); } } }); } catch (Exception ex) { tracer.TraceError(ex); return(false); } return(true); } }
public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory) { Console.WriteLine(@"Configure : " + DateTime.Now.ToString("hh.mm.ss.ffffff")); loggerFactory.AddEventSourceLogger(); KuduWebUtil.MigrateToNetCorePatch(_webAppRuntimeEnvironment); if (_hostingEnvironment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } var webSocketOptions = new WebSocketOptions() { KeepAliveInterval = TimeSpan.FromSeconds(15) }; app.UseWebSockets(webSocketOptions); var containsRelativePath = new Func <HttpContext, bool>(i => i.Request.Path.Value.StartsWith("/Default", StringComparison.OrdinalIgnoreCase)); app.MapWhen(containsRelativePath, application => application.Run(async context => { await context.Response.WriteAsync("Kestrel Running"); })); var containsRelativePath2 = new Func <HttpContext, bool>(i => i.Request.Path.Value.StartsWith("/info", StringComparison.OrdinalIgnoreCase)); app.MapWhen(containsRelativePath2, application => application.Run(async context => { await context.Response.WriteAsync("{\"Version\":\"" + Constants.KuduBuild + "\"}"); })); app.UseResponseCompression(); var containsRelativePath3 = new Func <HttpContext, bool>(i => i.Request.Path.Value.StartsWith("/AppServiceTunnel/Tunnel.ashx", StringComparison.OrdinalIgnoreCase)); app.MapWhen(containsRelativePath3, builder => builder.UseMiddleware <DebugExtensionMiddleware>()); app.UseTraceMiddleware(); applicationLifetime.ApplicationStopping.Register(OnShutdown); app.UseStaticFiles(); ProxyRequestIfRelativeUrlMatches(@"/webssh", "http", "127.0.0.1", "3000", app); var configuration = app.ApplicationServices.GetRequiredService <IServerConfiguration>(); // CORE TODO any equivalent for this? Needed? //var configuration = kernel.Get<IServerConfiguration>(); //GlobalConfiguration.Configuration.Formatters.Clear(); //GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; var jsonFormatter = new JsonMediaTypeFormatter(); // CORE TODO concept of "deprecation" in routes for traces, Do we need this for linux ? // Push url foreach (var url in new[] { "/git-receive-pack", $"/{configuration.GitServerRoot}/git-receive-pack" }) { app.Map(url, appBranch => appBranch.RunReceivePackHandler()); } // Fetch hook app.Map("/deploy", appBranch => appBranch.RunFetchHandler()); // Log streaming app.Map("/api/logstream", appBranch => appBranch.RunLogStreamHandler()); // Clone url foreach (var url in new[] { "/git-upload-pack", $"/{configuration.GitServerRoot}/git-upload-pack" }) { app.Map(url, appBranch => appBranch.RunUploadPackHandler()); } // Custom GIT repositories, which can be served from any directory that has a git repo foreach (var url in new[] { "/git-custom-repository", "/git/{*path}" }) { app.Map(url, appBranch => appBranch.RunCustomGitRepositoryHandler()); } // Sets up the file server to web app's wwwroot KuduWebUtil.SetupFileServer(app, _webAppRuntimeEnvironment.WebRootPath, "/wwwroot"); // Sets up the file server to LogFiles KuduWebUtil.SetupFileServer(app, Path.Combine(_webAppRuntimeEnvironment.LogFilesPath, "kudu", "deployment"), "/deploymentlogs"); app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Kudu API Docs"); }); app.UseMvc(routes => { Console.WriteLine(@"Setting Up Routes : " + DateTime.Now.ToString("hh.mm.ss.ffffff")); routes.MapRouteAnalyzer("/routes"); // Add routes.MapRoute( name: "default", template: "{controller}/{action=Index}/{id?}"); // Git Service routes.MapRoute("git-info-refs-root", "info/refs", new { controller = "InfoRefs", action = "Execute" }); routes.MapRoute("git-info-refs", configuration.GitServerRoot + "/info/refs", new { controller = "InfoRefs", action = "Execute" }); // Scm (deployment repository) routes.MapHttpRouteDual("scm-info", "scm/info", new { controller = "LiveScm", action = "GetRepositoryInfo" }); routes.MapHttpRouteDual("scm-clean", "scm/clean", new { controller = "LiveScm", action = "Clean" }); routes.MapHttpRouteDual("scm-delete", "scm", new { controller = "LiveScm", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Scm files editor routes.MapHttpRouteDual("scm-get-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "GetItem" }, new { verb = new HttpMethodRouteConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("scm-put-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "PutItem" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("scm-delete-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "DeleteItem" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Live files editor routes.MapHttpRouteDual("vfs-get-files", "vfs/{*path}", new { controller = "Vfs", action = "GetItem" }, new { verb = new HttpMethodRouteConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("vfs-put-files", "vfs/{*path}", new { controller = "Vfs", action = "PutItem" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("vfs-delete-files", "vfs/{*path}", new { controller = "Vfs", action = "DeleteItem" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Zip file handler routes.MapHttpRouteDual("zip-get-files", "zip/{*path}", new { controller = "Zip", action = "GetItem" }, new { verb = new HttpMethodRouteConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("zip-put-files", "zip/{*path}", new { controller = "Zip", action = "PutItem" }, new { verb = new HttpMethodRouteConstraint("PUT") }); // Zip push deployment routes.MapRoute("zip-push-deploy", "api/zipdeploy", new { controller = "PushDeployment", action = "ZipPushDeploy" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapRoute("zip-war-deploy", "api/wardeploy", new { controller = "PushDeployment", action = "WarPushDeploy" }, new { verb = new HttpMethodRouteConstraint("POST") }); // Live Command Line routes.MapHttpRouteDual("execute-command", "command", new { controller = "Command", action = "ExecuteCommand" }, new { verb = new HttpMethodRouteConstraint("POST") }); // Deployments routes.MapHttpRouteDual("all-deployments", "deployments", new { controller = "Deployment", action = "GetDeployResults" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("one-deployment-get", "deployments/{id}", new { controller = "Deployment", action = "GetResult" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("one-deployment-put", "deployments/{id?}", new { controller = "Deployment", action = "Deploy" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("one-deployment-delete", "deployments/{id}", new { controller = "Deployment", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); routes.MapHttpRouteDual("one-deployment-log", "deployments/{id}/log", new { controller = "Deployment", action = "GetLogEntry" }); routes.MapHttpRouteDual("one-deployment-log-details", "deployments/{id}/log/{logId}", new { controller = "Deployment", action = "GetLogEntryDetails" }); // Deployment script routes.MapRoute("get-deployment-script", "api/deploymentscript", new { controller = "Deployment", action = "GetDeploymentScript" }, new { verb = new HttpMethodRouteConstraint("GET") }); // IsDeploying status routes.MapRoute("is-deployment-underway", "api/isdeploying", new { controller = "Deployment", action = "IsDeploying" }, new { verb = new HttpMethodRouteConstraint("GET") }); // SSHKey routes.MapHttpRouteDual("get-sshkey", "api/sshkey", new { controller = "SSHKey", action = "GetPublicKey" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("put-sshkey", "api/sshkey", new { controller = "SSHKey", action = "SetPrivateKey" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("delete-sshkey", "api/sshkey", new { controller = "SSHKey", action = "DeleteKeyPair" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Environment routes.MapHttpRouteDual("get-env", "environment", new { controller = "Environment", action = "Get" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Settings routes.MapHttpRouteDual("set-setting", "settings", new { controller = "Settings", action = "Set" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapHttpRouteDual("get-all-settings", "settings", new { controller = "Settings", action = "GetAll" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("get-setting", "settings/{key}", new { controller = "Settings", action = "Get" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("delete-setting", "settings/{key}", new { controller = "Settings", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Diagnostics routes.MapHttpRouteDual("diagnostics", "dump", new { controller = "Diagnostics", action = "GetLog" }); routes.MapHttpRouteDual("diagnostics-set-setting", "diagnostics/settings", new { controller = "Diagnostics", action = "Set" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapHttpRouteDual("diagnostics-get-all-settings", "diagnostics/settings", new { controller = "Diagnostics", action = "GetAll" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("diagnostics-get-setting", "diagnostics/settings/{key}", new { controller = "Diagnostics", action = "Get" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("diagnostics-delete-setting", "diagnostics/settings/{key}", new { controller = "Diagnostics", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Logs foreach (var url in new[] { "/logstream", "/logstream/{*path}" }) { app.Map(url, appBranch => appBranch.RunLogStreamHandler()); } routes.MapHttpRouteDual("recent-logs", "api/logs/recent", new { controller = "Diagnostics", action = "GetRecentLogs" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Enable these for Linux and Windows Containers. if (!OSDetector.IsOnWindows() || (OSDetector.IsOnWindows() && EnvironmentHelper.IsWindowsContainers())) { routes.MapRoute("current-docker-logs-zip", "api/logs/docker/zip", new { controller = "Diagnostics", action = "GetDockerLogsZip" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapRoute("current-docker-logs", "api/logs/docker", new { controller = "Diagnostics", action = "GetDockerLogs" }, new { verb = new HttpMethodRouteConstraint("GET") }); } var processControllerName = OSDetector.IsOnWindows() ? "Process" : "LinuxProcess"; // Processes routes.MapHttpProcessesRoute("all-processes", "", new { controller = processControllerName, action = "GetAllProcesses" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-get", "/{id}", new { controller = processControllerName, action = "GetProcess" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-delete", "/{id}", new { controller = processControllerName, action = "KillProcess" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); routes.MapHttpProcessesRoute("one-process-dump", "/{id}/dump", new { controller = processControllerName, action = "MiniDump" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("start-process-profile", "/{id}/profile/start", new { controller = processControllerName, action = "StartProfileAsync" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapHttpProcessesRoute("stop-process-profile", "/{id}/profile/stop", new { controller = processControllerName, action = "StopProfileAsync" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("all-threads", "/{id}/threads", new { controller = processControllerName, action = "GetAllThreads" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-thread", "/{processId}/threads/{threadId}", new { controller = processControllerName, action = "GetThread" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("all-modules", "/{id}/modules", new { controller = processControllerName, action = "GetAllModules" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-module", "/{id}/modules/{baseAddress}", new { controller = processControllerName, action = "GetModule" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Runtime routes.MapHttpRouteDual("runtime", "diagnostics/runtime", new { controller = "Runtime", action = "GetRuntimeVersions" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Docker Hook Endpoint if (!OSDetector.IsOnWindows() || (OSDetector.IsOnWindows() && EnvironmentHelper.IsWindowsContainers())) { routes.MapHttpRouteDual("docker", "docker/hook", new { controller = "Docker", action = "ReceiveHook" }, new { verb = new HttpMethodRouteConstraint("POST") }); } // catch all unregistered url to properly handle not found // routes.MapRoute("error-404", "{*path}", new {controller = "Error404", action = "Handle"}); }); Console.WriteLine(@"Exiting Configure : " + DateTime.Now.ToString("hh.mm.ss.ffffff")); }
public ActionResult Index() { var os = OSDetector.IsOnWindows() ? "Windows" : "Linux"; return(View($"~/Pages/ZipDeploy/{os}ZipDeploy.cshtml")); }
public void Initialize() { var tracer = _tracerFactory.GetTracer(); using (tracer.Step("LibGit2SharpRepository Initialize")) { var dotGitPath = LibGit2Sharp.Repository.Init(RepositoryPath); using (var repo = new LibGit2Sharp.Repository(dotGitPath)) { repo.Config.Set("core.autocrlf", OSDetector.IsOnWindows()); // This speeds up git operations like 'git checkout', especially on slow drives like in Azure repo.Config.Set("core.preloadindex", true); repo.Config.Set("user.name", _settings.GetGitUsername()); repo.Config.Set("user.email", _settings.GetGitEmail()); // This is needed to make lfs work repo.Config.Set("filter.lfs.clean", "git-lfs clean %f"); repo.Config.Set("filter.lfs.smudge", "git-lfs smudge %f"); repo.Config.Set("filter.lfs.required", true); using (tracer.Step("Configure git server")) { // Allow getting pushes even though we're not bare repo.Config.Set("receive.denyCurrentBranch", "ignore"); } // to disallow browsing to this folder in case of in-place repo using (tracer.Step("Create deny users for .git folder")) { string content = "<?xml version=\"1.0\"" + @"?> <configuration> <system.web> <authorization> <deny users=" + "\"*\"" + @"/> </authorization> </system.web> <configuration>"; File.WriteAllText(Path.Combine(dotGitPath, "web.config"), content); } // Server env does not support interactive cred prompt; hence, we intercept any credential provision // for git fetch/clone with http/https scheme and return random invalid u/p forcing 'fatal: Authentication failed.' using (tracer.Step("Configure git-credential")) { FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(GitCredentialHookPath)); string content = @"#!/bin/sh if [ " + "\"$1\" = \"get\"" + @" ]; then echo username=dummyUser echo password=dummyPassword fi" + "\n"; File.WriteAllText(GitCredentialHookPath, content); repo.Config.Set("credential.helper", string.Format("!'{0}'", GitCredentialHookPath)); } } using (tracer.Step("Setup post receive hook")) { FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(PostReceiveHookPath)); string content = @"#!/bin/sh read i echo $i > pushinfo " + KnownEnvironment.KUDUCOMMAND + "\r\n"; File.WriteAllText(PostReceiveHookPath, content); } // NOTE: don't add any new init steps after creating the post receive hook, // as it's also used to mark that Init was fully executed } }
public ActionResult Index() { var os = OSDetector.IsOnWindows() ? "Windows" : "Linux"; return(View($"~/Pages/DebugConsole/{os}Console.cshtml")); }
public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory) { Console.WriteLine("\nConfigure : " + DateTime.Now.ToString("hh.mm.ss.ffffff")); loggerFactory.AddEventSourceLogger(); if (_hostingEnvironment.IsDevelopment()) { app.UseDeveloperExceptionPage(); //app.UseBrowserLink(); } else { // CORE TODO app.UseExceptionHandler("/Error"); } var containsRelativePath = new Func <HttpContext, bool>(i => i.Request.Path.Value.StartsWith("/Default", StringComparison.OrdinalIgnoreCase)); app.MapWhen(containsRelativePath, application => application.Run(async context => { //context.Response.StatusCode = StatusCodes.Status500InternalServerError; await context.Response.WriteAsync("Kestrel Running"); })); var containsRelativePath2 = new Func <HttpContext, bool>(i => i.Request.Path.Value.StartsWith("/Version", StringComparison.OrdinalIgnoreCase)); app.MapWhen(containsRelativePath2, application => application.Run(async context => { //context.Response.StatusCode = StatusCodes.Status500InternalServerError; await context.Response.WriteAsync("KuduL:2"); })); app.UseResponseCompression(); var containsRelativePath3 = new Func <HttpContext, bool>(i => i.Request.Path.Value.StartsWith("/api/debugext2", StringComparison.OrdinalIgnoreCase)); //app.Map("/api/debugext2", a => a.UseMiddleware<DebugExtensionMiddleware>()); app.MapWhen(containsRelativePath3, builder => builder.UseMiddleware <DebugExtensionMiddleware>()); applicationLifetime.ApplicationStopping.Register(OnShutdown); app.UseStaticFiles(); ProxyRequestsIfRelativeUrlMatch(@"/webssh", "http", "127.0.0.1", "3000", app); ProxyRequestsIfRelativeUrlMatch(@"/AppServiceTunnel/Tunnel.ashx", "http", "127.0.0.1", "5000", app); ProxyRequestsIfRelativeUrlMatch(@"/AppServiceTunnel/Tunnel.ashx", "http", "127.0.0.1", "5000", app); var configuration = app.ApplicationServices.GetRequiredService <IServerConfiguration>(); // CORE TODO any equivalent for this? Needed? //var configuration = kernel.Get<IServerConfiguration>(); //GlobalConfiguration.Configuration.Formatters.Clear(); //GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; var jsonFormatter = new JsonMediaTypeFormatter(); //GlobalConfiguration.Configuration.Formatters.Add(jsonFormatter); //GlobalConfiguration.Configuration.DependencyResolver = new NinjectWebApiDependencyResolver(kernel); //GlobalConfiguration.Configuration.Filters.Add(new TraceExceptionFilterAttribute()); // CORE TODO concept of "deprecation" in routes for traces // Push url foreach (var url in new[] { "/git-receive-pack", $"/{configuration.GitServerRoot}/git-receive-pack" }) { app.Map(url, appBranch => appBranch.RunReceivePackHandler()); } ; // Fetch hook app.Map("/deploy", appBranch => appBranch.RunFetchHandler()); // Log streaming app.Map("/api/logstream", appBranch => appBranch.RunLogStreamHandler()); // Clone url foreach (var url in new[] { "/git-upload-pack", $"/{configuration.GitServerRoot}/git-upload-pack" }) { app.Map(url, appBranch => appBranch.RunUploadPackHandler()); } ; // CORE TODO // Custom GIT repositories, which can be served from any directory that has a git repo //routes.MapHandler<CustomGitRepositoryHandler>(kernel, "git-custom-repository", "git/{*path}", deprecated: false); // Custom GIT repositories, which can be served from any directory that has a git repo foreach (var url in new[] { "/git-custom-repository", "/git/{*path}" }) { app.Map(url, appBranch => appBranch.RunCustomGitRepositoryHandler()); } ; app.UseFileServer(new FileServerOptions { FileProvider = new PhysicalFileProvider( _webAppEnvironment.WebRootPath), RequestPath = "/wwwroot", EnableDirectoryBrowsing = true }); app.UseTraceMiddleware(); //app.UseStaticFiles(); app.UseMvc(routes => { Console.WriteLine("\nSetting Up Routes : " + DateTime.Now.ToString("hh.mm.ss.ffffff")); // CORE TODO Default route needed? routes.MapRoute( name: "default", template: "{controller}/{action=Index}/{id?}"); // Git Service routes.MapRoute("git-info-refs-root", "info/refs", new { controller = "InfoRefs", action = "Execute" }); routes.MapRoute("git-info-refs", configuration.GitServerRoot + "/info/refs", new { controller = "InfoRefs", action = "Execute" }); // Scm (deployment repository) routes.MapHttpRouteDual("scm-info", "scm/info", new { controller = "LiveScm", action = "GetRepositoryInfo" }); routes.MapHttpRouteDual("scm-clean", "scm/clean", new { controller = "LiveScm", action = "Clean" }); routes.MapHttpRouteDual("scm-delete", "scm", new { controller = "LiveScm", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Scm files editor routes.MapHttpRouteDual("scm-get-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "GetItem" }, new { verb = new HttpMethodRouteConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("scm-put-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "PutItem" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("scm-delete-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "DeleteItem" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Live files editor routes.MapHttpRouteDual("vfs-get-files", "vfs/{*path}", new { controller = "Vfs", action = "GetItem" }, new { verb = new HttpMethodRouteConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("vfs-put-files", "vfs/{*path}", new { controller = "Vfs", action = "PutItem" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("vfs-delete-files", "vfs/{*path}", new { controller = "Vfs", action = "DeleteItem" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Zip file handler routes.MapHttpRouteDual("zip-get-files", "zip/{*path}", new { controller = "Zip", action = "GetItem" }, new { verb = new HttpMethodRouteConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("zip-put-files", "zip/{*path}", new { controller = "Zip", action = "PutItem" }, new { verb = new HttpMethodRouteConstraint("PUT") }); // Zip push deployment routes.MapRoute("zip-push-deploy", "api/zipdeploy", new { controller = "PushDeployment", action = "ZipPushDeploy" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapRoute("zip-war-deploy", "api/wardeploy", new { controller = "PushDeployment", action = "WarPushDeploy" }, new { verb = new HttpMethodRouteConstraint("POST") }); // Live Command Line routes.MapHttpRouteDual("execute-command", "command", new { controller = "Command", action = "ExecuteCommand" }, new { verb = new HttpMethodRouteConstraint("POST") }); // Deployments routes.MapHttpRouteDual("all-deployments", "deployments", new { controller = "Deployment", action = "GetDeployResults" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("one-deployment-get", "deployments/{id}", new { controller = "Deployment", action = "GetResult" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("one-deployment-put", "deployments/{id?}", new { controller = "Deployment", action = "Deploy" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("one-deployment-delete", "deployments/{id}", new { controller = "Deployment", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); routes.MapHttpRouteDual("one-deployment-log", "deployments/{id}/log", new { controller = "Deployment", action = "GetLogEntry" }); routes.MapHttpRouteDual("one-deployment-log-details", "deployments/{id}/log/{logId}", new { controller = "Deployment", action = "GetLogEntryDetails" }); // Deployment script routes.MapRoute("get-deployment-script", "api/deploymentscript", new { controller = "Deployment", action = "GetDeploymentScript" }, new { verb = new HttpMethodRouteConstraint("GET") }); // CORE TODO // SSHKey routes.MapHttpRouteDual("get-sshkey", "api/sshkey", new { controller = "SSHKey", action = "GetPublicKey" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("put-sshkey", "api/sshkey", new { controller = "SSHKey", action = "SetPrivateKey" }, new { verb = new HttpMethodRouteConstraint("PUT") }); routes.MapHttpRouteDual("delete-sshkey", "api/sshkey", new { controller = "SSHKey", action = "DeleteKeyPair" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Environment routes.MapHttpRouteDual("get-env", "environment", new { controller = "Environment", action = "Get" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Settings routes.MapHttpRouteDual("set-setting", "settings", new { controller = "Settings", action = "Set" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapHttpRouteDual("get-all-settings", "settings", new { controller = "Settings", action = "GetAll" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("get-setting", "settings/{key}", new { controller = "Settings", action = "Get" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("delete-setting", "settings/{key}", new { controller = "Settings", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // Diagnostics routes.MapHttpRouteDual("diagnostics", "dump", new { controller = "Diagnostics", action = "GetLog" }); routes.MapHttpRouteDual("diagnostics-set-setting", "diagnostics/settings", new { controller = "Diagnostics", action = "Set" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapHttpRouteDual("diagnostics-get-all-settings", "diagnostics/settings", new { controller = "Diagnostics", action = "GetAll" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("diagnostics-get-setting", "diagnostics/settings/{key}", new { controller = "Diagnostics", action = "Get" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpRouteDual("diagnostics-delete-setting", "diagnostics/settings/{key}", new { controller = "Diagnostics", action = "Delete" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); // CORE TODO // Logs foreach (var url in new[] { "/logstream", "/logstream/{*path}" }) { app.Map(url, appBranch => appBranch.RunLogStreamHandler()); } ; //routes.MapHttpRouteDual<LogStreamHandler>(kernel, "logstream", "logstream/{*path}"); routes.MapHttpRouteDual("recent-logs", "api/logs/recent", new { controller = "Diagnostics", action = "GetRecentLogs" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Enable these for Linux and Windows Containers. if (!OSDetector.IsOnWindows() || (OSDetector.IsOnWindows() && EnvironmentHelper.IsWindowsContainers())) { routes.MapRoute("current-docker-logs-zip", "api/logs/docker/zip", new { controller = "Diagnostics", action = "GetDockerLogsZip" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapRoute("current-docker-logs", "api/logs/docker", new { controller = "Diagnostics", action = "GetDockerLogs" }, new { verb = new HttpMethodRouteConstraint("GET") }); } // CORE TODO var processControllerName = OSDetector.IsOnWindows() ? "Process" : "LinuxProcess"; // Processes routes.MapHttpProcessesRoute("all-processes", "", new { controller = processControllerName, action = "GetAllProcesses" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-get", "/{id}", new { controller = processControllerName, action = "GetProcess" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-delete", "/{id}", new { controller = processControllerName, action = "KillProcess" }, new { verb = new HttpMethodRouteConstraint("DELETE") }); routes.MapHttpProcessesRoute("one-process-dump", "/{id}/dump", new { controller = processControllerName, action = "MiniDump" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("start-process-profile", "/{id}/profile/start", new { controller = processControllerName, action = "StartProfileAsync" }, new { verb = new HttpMethodRouteConstraint("POST") }); routes.MapHttpProcessesRoute("stop-process-profile", "/{id}/profile/stop", new { controller = processControllerName, action = "StopProfileAsync" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("all-threads", "/{id}/threads", new { controller = processControllerName, action = "GetAllThreads" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-thread", "/{processId}/threads/{threadId}", new { controller = processControllerName, action = "GetThread" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("all-modules", "/{id}/modules", new { controller = processControllerName, action = "GetAllModules" }, new { verb = new HttpMethodRouteConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-module", "/{id}/modules/{baseAddress}", new { controller = processControllerName, action = "GetModule" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Runtime routes.MapHttpRouteDual("runtime", "diagnostics/runtime", new { controller = "Runtime", action = "GetRuntimeVersions" }, new { verb = new HttpMethodRouteConstraint("GET") }); // Hooks //routes.MapHttpRouteDual("unsubscribe-hook", "hooks/{id}", new { controller = "WebHooks", action = "Unsubscribe" }, new { verb = new HttpMethodConstraint("DELETE") }); //routes.MapHttpRouteDual("get-hook", "hooks/{id}", new { controller = "WebHooks", action = "GetWebHook" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRouteDual("publish-hooks", "hooks/publish/{hookEventType}", new { controller = "WebHooks", action = "PublishEvent" }, new { verb = new HttpMethodConstraint("POST") }); //routes.MapHttpRouteDual("get-hooks", "hooks", new { controller = "WebHooks", action = "GetWebHooks" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRouteDual("subscribe-hook", "hooks", new { controller = "WebHooks", action = "Subscribe" }, new { verb = new HttpMethodConstraint("POST") }); // Jobs //routes.MapHttpWebJobsRoute("list-all-jobs", "", "", new { controller = "Jobs", action = "ListAllJobs" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("list-triggered-jobs", "triggered", "", new { controller = "Jobs", action = "ListTriggeredJobs" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("get-triggered-job", "triggered", "/{jobName}", new { controller = "Jobs", action = "GetTriggeredJob" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("invoke-triggered-job", "triggered", "/{jobName}/run", new { controller = "Jobs", action = "InvokeTriggeredJob" }, new { verb = new HttpMethodConstraint("POST") }); //routes.MapHttpWebJobsRoute("get-triggered-job-history", "triggered", "/{jobName}/history", new { controller = "Jobs", action = "GetTriggeredJobHistory" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("get-triggered-job-run", "triggered", "/{jobName}/history/{runId}", new { controller = "Jobs", action = "GetTriggeredJobRun" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("create-triggered-job", "triggered", "/{jobName}", new { controller = "Jobs", action = "CreateTriggeredJob" }, new { verb = new HttpMethodConstraint("PUT") }); //routes.MapHttpWebJobsRoute("remove-triggered-job", "triggered", "/{jobName}", new { controller = "Jobs", action = "RemoveTriggeredJob" }, new { verb = new HttpMethodConstraint("DELETE") }); //routes.MapHttpWebJobsRoute("get-triggered-job-settings", "triggered", "/{jobName}/settings", new { controller = "Jobs", action = "GetTriggeredJobSettings" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("set-triggered-job-settings", "triggered", "/{jobName}/settings", new { controller = "Jobs", action = "SetTriggeredJobSettings" }, new { verb = new HttpMethodConstraint("PUT") }); //routes.MapHttpWebJobsRoute("list-continuous-jobs", "continuous", "", new { controller = "Jobs", action = "ListContinuousJobs" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("get-continuous-job", "continuous", "/{jobName}", new { controller = "Jobs", action = "GetContinuousJob" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("disable-continuous-job", "continuous", "/{jobName}/stop", new { controller = "Jobs", action = "DisableContinuousJob" }, new { verb = new HttpMethodConstraint("POST") }); //routes.MapHttpWebJobsRoute("enable-continuous-job", "continuous", "/{jobName}/start", new { controller = "Jobs", action = "EnableContinuousJob" }, new { verb = new HttpMethodConstraint("POST") }); //routes.MapHttpWebJobsRoute("create-continuous-job", "continuous", "/{jobName}", new { controller = "Jobs", action = "CreateContinuousJob" }, new { verb = new HttpMethodConstraint("PUT") }); //routes.MapHttpWebJobsRoute("remove-continuous-job", "continuous", "/{jobName}", new { controller = "Jobs", action = "RemoveContinuousJob" }, new { verb = new HttpMethodConstraint("DELETE") }); //routes.MapHttpWebJobsRoute("get-continuous-job-settings", "continuous", "/{jobName}/settings", new { controller = "Jobs", action = "GetContinuousJobSettings" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpWebJobsRoute("set-continuous-job-settings", "continuous", "/{jobName}/settings", new { controller = "Jobs", action = "SetContinuousJobSettings" }, new { verb = new HttpMethodConstraint("PUT") }); //routes.MapHttpWebJobsRoute("request-passthrough-continuous-job", "continuous", "/{jobName}/passthrough/{*path}", new { controller = "Jobs", action = "RequestPassthrough" }, new { verb = new HttpMethodConstraint("GET", "HEAD", "PUT", "POST", "DELETE", "PATCH") }); // Web Jobs as microservice //routes.MapHttpRoute("list-triggered-jobs-swagger", "api/triggeredwebjobsswagger", new { controller = "Jobs", action = "ListTriggeredJobsInSwaggerFormat" }, new { verb = new HttpMethodConstraint("GET") }); // SiteExtensions //routes.MapHttpRoute("api-get-remote-extensions", "api/extensionfeed", new { controller = "SiteExtension", action = "GetRemoteExtensions" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("api-get-remote-extension", "api/extensionfeed/{id}", new { controller = "SiteExtension", action = "GetRemoteExtension" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("api-get-local-extensions", "api/siteextensions", new { controller = "SiteExtension", action = "GetLocalExtensions" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("api-get-local-extension", "api/siteextensions/{id}", new { controller = "SiteExtension", action = "GetLocalExtension" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("api-uninstall-extension", "api/siteextensions/{id}", new { controller = "SiteExtension", action = "UninstallExtension" }, new { verb = new HttpMethodConstraint("DELETE") }); //routes.MapHttpRoute("api-install-update-extension", "api/siteextensions/{id}", new { controller = "SiteExtension", action = "InstallExtension" }, new { verb = new HttpMethodConstraint("PUT") }); // Functions //routes.MapHttpRoute("get-functions-host-settings", "api/functions/config", new { controller = "Function", action = "GetHostSettings" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("put-functions-host-settings", "api/functions/config", new { controller = "Function", action = "PutHostSettings" }, new { verb = new HttpMethodConstraint("PUT") }); //routes.MapHttpRoute("api-sync-functions", "api/functions/synctriggers", new { controller = "Function", action = "SyncTriggers" }, new { verb = new HttpMethodConstraint("POST") }); // This route only needed for temporary workaround. Will yank when /syncfunctionapptriggers is supported in ARM //routes.MapHttpRoute("api-sync-functions-tmphack", "functions/listsynctriggers", new { controller = "Function", action = "SyncTriggers" }, new { verb = new HttpMethodConstraint("POST") }); //routes.MapHttpRoute("put-function", "api/functions/{name}", new { controller = "Function", action = "CreateOrUpdate" }, new { verb = new HttpMethodConstraint("PUT") }); //routes.MapHttpRoute("list-functions", "api/functions", new { controller = "Function", action = "List" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("get-function", "api/functions/{name}", new { controller = "Function", action = "Get" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("list-secrets", "api/functions/{name}/listsecrets", new { controller = "Function", action = "GetSecrets" }, new { verb = new HttpMethodConstraint("POST") }); //routes.MapHttpRoute("get-masterkey", "api/functions/admin/masterkey", new { controller = "Function", action = "GetMasterKey" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("get-admintoken", "api/functions/admin/token", new { controller = "Function", action = "GetAdminToken" }, new { verb = new HttpMethodConstraint("GET") }); //routes.MapHttpRoute("delete-function", "api/functions/{name}", new { controller = "Function", action = "Delete" }, new { verb = new HttpMethodConstraint("DELETE") }); //routes.MapHttpRoute("download-functions", "api/functions/admin/download", new { controller = "Function", action = "DownloadFunctions" }, new { verb = new HttpMethodConstraint("GET") }); // Docker Hook Endpoint if (!OSDetector.IsOnWindows() || (OSDetector.IsOnWindows() && EnvironmentHelper.IsWindowsContainers())) { routes.MapHttpRouteDual("docker", "docker/hook", new { controller = "Docker", action = "ReceiveHook" }, new { verb = new HttpMethodRouteConstraint("POST") }); } // catch all unregistered url to properly handle not found // this is to work arounf the issue in TraceModule where we see double OnBeginRequest call // for the same request (404 and then 200 statusCode). //routes.MapRoute("error-404", "{*path}", new { controller = "Error404", action = "Handle" }); }); // CORE TODO Remove This /* * var containsRelativePath2 = new Func<HttpContext, bool>(i => * i.Request.Path.Value.StartsWith("/TestException", StringComparison.OrdinalIgnoreCase)); * * app.MapWhen(containsRelativePath2, application => application.Run(async context => * { * //context.Response.StatusCode = StatusCodes.Status500InternalServerError; * //await context.Response.WriteAsync("Kestrel Running"); * throw new Exception("Exception Handler Test"); * })); */ /* * app.Run(async context => * { * await context.Response.WriteAsync("Krestel Running"); // returns a 200 * }); */ Console.WriteLine("\nExiting Configure : " + DateTime.Now.ToString("hh.mm.ss.ffffff")); }
public static IDictionary <string, string> Extract(this ZipArchive archive, string directoryName, bool preserveSymlinks = false) { IDictionary <string, string> symLinks = new Dictionary <string, string>(); bool isSymLink = false; foreach (ZipArchiveEntry entry in archive.Entries) { string path = Path.Combine(directoryName, entry.FullName); if (entry.Length == 0 && (path.EndsWith("/", StringComparison.Ordinal) || path.EndsWith("\\", StringComparison.Ordinal))) { // Extract directory FileSystemHelpers.CreateDirectory(path); } else { FileInfoBase fileInfo = FileSystemHelpers.FileInfoFromFileName(path); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } using (Stream zipStream = entry.Open(), fileStream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { zipStream.CopyTo(fileStream); } isSymLink = false; string originalFileName = string.Empty; if (!OSDetector.IsOnWindows()) { try { using (Stream fs = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { byte[] buffer = new byte[4]; fs.Read(buffer, 0, buffer.Length); fs.Close(); var str = System.Text.Encoding.Default.GetString(buffer); if (preserveSymlinks && str.StartsWith("../")) { using (StreamReader reader = fileInfo.OpenText()) { symLinks[entry.FullName] = reader.ReadToEnd(); } isSymLink = true; } } } catch (Exception ex) { throw new Exception("Could not identify symlinks in zip file : " + ex.ToString()); } } try { fileInfo.LastWriteTimeUtc = entry.LastWriteTime.ToUniversalTime().DateTime; } catch (Exception) { //best effort } if (isSymLink) { fileInfo.Delete(); } } } return(symLinks); }
public static void RegisterRoutes(IKernel kernel, RouteCollection routes) { var configuration = kernel.Get <IServerConfiguration>(); GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; var jsonFormatter = new JsonMediaTypeFormatter(); GlobalConfiguration.Configuration.Formatters.Add(jsonFormatter); GlobalConfiguration.Configuration.DependencyResolver = new NinjectWebApiDependencyResolver(kernel); GlobalConfiguration.Configuration.Filters.Add(new TraceExceptionFilterAttribute()); // Git Service routes.MapHttpRoute("git-info-refs-root", "info/refs", new { controller = "InfoRefs", action = "Execute" }); routes.MapHttpRoute("git-info-refs", configuration.GitServerRoot + "/info/refs", new { controller = "InfoRefs", action = "Execute" }); // Push url routes.MapHandler <ReceivePackHandler>(kernel, "git-receive-pack-root", "git-receive-pack", deprecated: false); routes.MapHandler <ReceivePackHandler>(kernel, "git-receive-pack", configuration.GitServerRoot + "/git-receive-pack", deprecated: false); // Fetch Hook routes.MapHandler <FetchHandler>(kernel, "fetch", "deploy", deprecated: false); // Clone url routes.MapHandler <UploadPackHandler>(kernel, "git-upload-pack-root", "git-upload-pack", deprecated: false); routes.MapHandler <UploadPackHandler>(kernel, "git-upload-pack", configuration.GitServerRoot + "/git-upload-pack", deprecated: false); // Custom GIT repositories, which can be served from any directory that has a git repo routes.MapHandler <CustomGitRepositoryHandler>(kernel, "git-custom-repository", "git/{*path}", deprecated: false); // Scm (deployment repository) routes.MapHttpRouteDual("scm-info", "scm/info", new { controller = "LiveScm", action = "GetRepositoryInfo" }); routes.MapHttpRouteDual("scm-clean", "scm/clean", new { controller = "LiveScm", action = "Clean" }); routes.MapHttpRouteDual("scm-delete", "scm", new { controller = "LiveScm", action = "Delete" }, new { verb = new HttpMethodConstraint("DELETE") }); // Scm files editor routes.MapHttpRouteDual("scm-get-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "GetItem" }, new { verb = new HttpMethodConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("scm-put-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "PutItem" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpRouteDual("scm-delete-files", "scmvfs/{*path}", new { controller = "LiveScmEditor", action = "DeleteItem" }, new { verb = new HttpMethodConstraint("DELETE") }); // Live files editor routes.MapHttpRouteDual("vfs-get-files", "vfs/{*path}", new { controller = "Vfs", action = "GetItem" }, new { verb = new HttpMethodConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("vfs-put-files", "vfs/{*path}", new { controller = "Vfs", action = "PutItem" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpRouteDual("vfs-delete-files", "vfs/{*path}", new { controller = "Vfs", action = "DeleteItem" }, new { verb = new HttpMethodConstraint("DELETE") }); // Zip file handler routes.MapHttpRouteDual("zip-get-files", "zip/{*path}", new { controller = "Zip", action = "GetItem" }, new { verb = new HttpMethodConstraint("GET", "HEAD") }); routes.MapHttpRouteDual("zip-put-files", "zip/{*path}", new { controller = "Zip", action = "PutItem" }, new { verb = new HttpMethodConstraint("PUT") }); // Zip push deployment routes.MapHttpRoute("zip-push-deploy", "api/zipdeploy", new { controller = "PushDeployment", action = "ZipPushDeploy" }, new { verb = new HttpMethodConstraint("POST") }); // Live Command Line routes.MapHttpRouteDual("execute-command", "command", new { controller = "Command", action = "ExecuteCommand" }, new { verb = new HttpMethodConstraint("POST") }); // Deployments routes.MapHttpRouteDual("all-deployments", "deployments", new { controller = "Deployment", action = "GetDeployResults" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("one-deployment-get", "deployments/{id}", new { controller = "Deployment", action = "GetResult" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("one-deployment-put", "deployments/{id}", new { controller = "Deployment", action = "Deploy", id = RouteParameter.Optional }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpRouteDual("one-deployment-delete", "deployments/{id}", new { controller = "Deployment", action = "Delete" }, new { verb = new HttpMethodConstraint("DELETE") }); routes.MapHttpRouteDual("one-deployment-log", "deployments/{id}/log", new { controller = "Deployment", action = "GetLogEntry" }); routes.MapHttpRouteDual("one-deployment-log-details", "deployments/{id}/log/{logId}", new { controller = "Deployment", action = "GetLogEntryDetails" }); // Deployment script routes.MapHttpRoute("get-deployment-script", "api/deploymentscript", new { controller = "Deployment", action = "GetDeploymentScript" }, new { verb = new HttpMethodConstraint("GET") }); // SSHKey routes.MapHttpRouteDual("get-sshkey", "sshkey", new { controller = "SSHKey", action = "GetPublicKey" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("put-sshkey", "sshkey", new { controller = "SSHKey", action = "SetPrivateKey" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpRouteDual("delete-sshkey", "sshkey", new { controller = "SSHKey", action = "DeleteKeyPair" }, new { verb = new HttpMethodConstraint("DELETE") }); // Environment routes.MapHttpRouteDual("get-env", "environment", new { controller = "Environment", action = "Get" }, new { verb = new HttpMethodConstraint("GET") }); // Settings routes.MapHttpRouteDual("set-setting", "settings", new { controller = "Settings", action = "Set" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpRouteDual("get-all-settings", "settings", new { controller = "Settings", action = "GetAll" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("get-setting", "settings/{key}", new { controller = "Settings", action = "Get" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("delete-setting", "settings/{key}", new { controller = "Settings", action = "Delete" }, new { verb = new HttpMethodConstraint("DELETE") }); // Diagnostics routes.MapHttpRouteDual("diagnostics", "dump", new { controller = "Diagnostics", action = "GetLog" }); routes.MapHttpRouteDual("diagnostics-set-setting", "diagnostics/settings", new { controller = "Diagnostics", action = "Set" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpRouteDual("diagnostics-get-all-settings", "diagnostics/settings", new { controller = "Diagnostics", action = "GetAll" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("diagnostics-get-setting", "diagnostics/settings/{key}", new { controller = "Diagnostics", action = "Get" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("diagnostics-delete-setting", "diagnostics/settings/{key}", new { controller = "Diagnostics", action = "Delete" }, new { verb = new HttpMethodConstraint("DELETE") }); // Logs routes.MapHandlerDual <LogStreamHandler>(kernel, "logstream", "logstream/{*path}"); routes.MapHttpRoute("recent-logs", "api/logs/recent", new { controller = "Diagnostics", action = "GetRecentLogs" }, new { verb = new HttpMethodConstraint("GET") }); if (!OSDetector.IsOnWindows()) { routes.MapHttpRoute("current-docker-logs-zip", "api/logs/docker/zip", new { controller = "Diagnostics", action = "GetDockerLogsZip" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("current-docker-logs", "api/logs/docker", new { controller = "Diagnostics", action = "GetDockerLogs" }, new { verb = new HttpMethodConstraint("GET") }); } var processControllerName = OSDetector.IsOnWindows() ? "Process" : "LinuxProcess"; // Processes routes.MapHttpProcessesRoute("all-processes", "", new { controller = processControllerName, action = "GetAllProcesses" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-get", "/{id}", new { controller = processControllerName, action = "GetProcess" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-delete", "/{id}", new { controller = processControllerName, action = "KillProcess" }, new { verb = new HttpMethodConstraint("DELETE") }); routes.MapHttpProcessesRoute("one-process-dump", "/{id}/dump", new { controller = processControllerName, action = "MiniDump" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpProcessesRoute("start-process-profile", "/{id}/profile/start", new { controller = processControllerName, action = "StartProfileAsync" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpProcessesRoute("stop-process-profile", "/{id}/profile/stop", new { controller = processControllerName, action = "StopProfileAsync" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpProcessesRoute("all-threads", "/{id}/threads", new { controller = processControllerName, action = "GetAllThreads" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-thread", "/{processId}/threads/{threadId}", new { controller = processControllerName, action = "GetThread" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpProcessesRoute("all-modules", "/{id}/modules", new { controller = processControllerName, action = "GetAllModules" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpProcessesRoute("one-process-module", "/{id}/modules/{baseAddress}", new { controller = processControllerName, action = "GetModule" }, new { verb = new HttpMethodConstraint("GET") }); // Runtime routes.MapHttpRouteDual("runtime", "diagnostics/runtime", new { controller = "Runtime", action = "GetRuntimeVersions" }, new { verb = new HttpMethodConstraint("GET") }); // Hooks routes.MapHttpRouteDual("unsubscribe-hook", "hooks/{id}", new { controller = "WebHooks", action = "Unsubscribe" }, new { verb = new HttpMethodConstraint("DELETE") }); routes.MapHttpRouteDual("get-hook", "hooks/{id}", new { controller = "WebHooks", action = "GetWebHook" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("publish-hooks", "hooks/publish/{hookEventType}", new { controller = "WebHooks", action = "PublishEvent" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpRouteDual("get-hooks", "hooks", new { controller = "WebHooks", action = "GetWebHooks" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRouteDual("subscribe-hook", "hooks", new { controller = "WebHooks", action = "Subscribe" }, new { verb = new HttpMethodConstraint("POST") }); // Jobs routes.MapHttpWebJobsRoute("list-all-jobs", "", "", new { controller = "Jobs", action = "ListAllJobs" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("list-triggered-jobs", "triggered", "", new { controller = "Jobs", action = "ListTriggeredJobs" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("get-triggered-job", "triggered", "/{jobName}", new { controller = "Jobs", action = "GetTriggeredJob" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("invoke-triggered-job", "triggered", "/{jobName}/run", new { controller = "Jobs", action = "InvokeTriggeredJob" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpWebJobsRoute("get-triggered-job-history", "triggered", "/{jobName}/history", new { controller = "Jobs", action = "GetTriggeredJobHistory" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("get-triggered-job-run", "triggered", "/{jobName}/history/{runId}", new { controller = "Jobs", action = "GetTriggeredJobRun" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("create-triggered-job", "triggered", "/{jobName}", new { controller = "Jobs", action = "CreateTriggeredJob" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpWebJobsRoute("remove-triggered-job", "triggered", "/{jobName}", new { controller = "Jobs", action = "RemoveTriggeredJob" }, new { verb = new HttpMethodConstraint("DELETE") }); routes.MapHttpWebJobsRoute("get-triggered-job-settings", "triggered", "/{jobName}/settings", new { controller = "Jobs", action = "GetTriggeredJobSettings" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("set-triggered-job-settings", "triggered", "/{jobName}/settings", new { controller = "Jobs", action = "SetTriggeredJobSettings" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpWebJobsRoute("list-continuous-jobs", "continuous", "", new { controller = "Jobs", action = "ListContinuousJobs" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("get-continuous-job", "continuous", "/{jobName}", new { controller = "Jobs", action = "GetContinuousJob" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("disable-continuous-job", "continuous", "/{jobName}/stop", new { controller = "Jobs", action = "DisableContinuousJob" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpWebJobsRoute("enable-continuous-job", "continuous", "/{jobName}/start", new { controller = "Jobs", action = "EnableContinuousJob" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpWebJobsRoute("create-continuous-job", "continuous", "/{jobName}", new { controller = "Jobs", action = "CreateContinuousJob" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpWebJobsRoute("remove-continuous-job", "continuous", "/{jobName}", new { controller = "Jobs", action = "RemoveContinuousJob" }, new { verb = new HttpMethodConstraint("DELETE") }); routes.MapHttpWebJobsRoute("get-continuous-job-settings", "continuous", "/{jobName}/settings", new { controller = "Jobs", action = "GetContinuousJobSettings" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpWebJobsRoute("set-continuous-job-settings", "continuous", "/{jobName}/settings", new { controller = "Jobs", action = "SetContinuousJobSettings" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpWebJobsRoute("request-passthrough-continuous-job", "continuous", "/{jobName}/passthrough/{*path}", new { controller = "Jobs", action = "RequestPassthrough" }, new { verb = new HttpMethodConstraint("GET", "HEAD", "PUT", "POST", "DELETE", "PATCH") }); // Web Jobs as microservice routes.MapHttpRoute("list-triggered-jobs-swagger", "api/triggeredwebjobsswagger", new { controller = "Jobs", action = "ListTriggeredJobsInSwaggerFormat" }, new { verb = new HttpMethodConstraint("GET") }); // SiteExtensions routes.MapHttpRoute("api-get-remote-extensions", "api/extensionfeed", new { controller = "SiteExtension", action = "GetRemoteExtensions" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("api-get-remote-extension", "api/extensionfeed/{id}", new { controller = "SiteExtension", action = "GetRemoteExtension" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("api-get-local-extensions", "api/siteextensions", new { controller = "SiteExtension", action = "GetLocalExtensions" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("api-get-local-extension", "api/siteextensions/{id}", new { controller = "SiteExtension", action = "GetLocalExtension" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("api-uninstall-extension", "api/siteextensions/{id}", new { controller = "SiteExtension", action = "UninstallExtension" }, new { verb = new HttpMethodConstraint("DELETE") }); routes.MapHttpRoute("api-install-update-extension", "api/siteextensions/{id}", new { controller = "SiteExtension", action = "InstallExtension" }, new { verb = new HttpMethodConstraint("PUT") }); // Functions routes.MapHttpRoute("get-functions-host-settings", "api/functions/config", new { controller = "Function", action = "GetHostSettings" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("put-functions-host-settings", "api/functions/config", new { controller = "Function", action = "PutHostSettings" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpRoute("api-sync-functions", "api/functions/synctriggers", new { controller = "Function", action = "SyncTriggers" }, new { verb = new HttpMethodConstraint("POST") }); // This route only needed for temporary workaround. Will yank when /syncfunctionapptriggers is supported in ARM routes.MapHttpRoute("api-sync-functions-tmphack", "functions/listsynctriggers", new { controller = "Function", action = "SyncTriggers" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpRoute("put-function", "api/functions/{name}", new { controller = "Function", action = "CreateOrUpdate" }, new { verb = new HttpMethodConstraint("PUT") }); routes.MapHttpRoute("list-functions", "api/functions", new { controller = "Function", action = "List" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("get-function", "api/functions/{name}", new { controller = "Function", action = "Get" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("list-secrets", "api/functions/{name}/listsecrets", new { controller = "Function", action = "GetSecrets" }, new { verb = new HttpMethodConstraint("POST") }); routes.MapHttpRoute("get-masterkey", "api/functions/admin/masterkey", new { controller = "Function", action = "GetMasterKey" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("get-admintoken", "api/functions/admin/token", new { controller = "Function", action = "GetAdminToken" }, new { verb = new HttpMethodConstraint("GET") }); routes.MapHttpRoute("delete-function", "api/functions/{name}", new { controller = "Function", action = "Delete" }, new { verb = new HttpMethodConstraint("DELETE") }); routes.MapHttpRoute("download-functions", "api/functions/admin/download", new { controller = "Function", action = "DownloadFunctions" }, new { verb = new HttpMethodConstraint("GET") }); // Docker Hook Endpoint if (!OSDetector.IsOnWindows()) { routes.MapHttpRoute("docker", "docker/hook", new { controller = "Docker", action = "ReceiveHook" }, new { verb = new HttpMethodConstraint("POST") }); } // catch all unregistered url to properly handle not found // this is to work arounf the issue in TraceModule where we see double OnBeginRequest call // for the same request (404 and then 200 statusCode). routes.MapHttpRoute("error-404", "{*path}", new { controller = "Error404", action = "Handle" }); }
private static string GetStartupFileName() { return(OSDetector.IsOnWindows() ? "startup.bat" : "startup.sh"); }