示例#1
0
        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);
                    }
                }
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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));
        }
示例#5
0
        /// <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);
             * }
             */
        }
示例#6
0
        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);
                }
            }
        }
示例#7
0
        /// <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);
            }
        }
示例#8
0
        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));
            }
        }
示例#9
0
        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);
        }
示例#10
0
        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
            }
        }
示例#11
0
        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;
        }
示例#12
0
        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);
                }
            }
        }
示例#13
0
 public static string GetStartupFileName()
 {
     return(OSDetector.IsOnWindows() ? "startup.cmd" : "startup.sh");
 }
示例#14
0
        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());
                        }
                    }
                }
            }
        }
示例#15
0
        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);
            }
        }
示例#16
0
        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"));
        }
示例#18
0
        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
            }
        }
示例#19
0
        public ActionResult Index()
        {
            var os = OSDetector.IsOnWindows() ? "Windows" : "Linux";

            return(View($"~/Pages/DebugConsole/{os}Console.cshtml"));
        }
示例#20
0
        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"));
        }
示例#21
0
        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);
        }
示例#22
0
        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" });
        }
示例#23
0
 private static string GetStartupFileName()
 {
     return(OSDetector.IsOnWindows() ? "startup.bat" : "startup.sh");
 }