public BuildOutputCommand(IJenkinsContext context, string jobName, string buildNumber) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } if (string.IsNullOrEmpty(buildNumber)) { throw new ArgumentException("'buildNumber' cannot be empty!"); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, buildNumber, "consoleText"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnReadAsync = async(response, token) => { using (var stream = response.GetResponseStream()) { if (stream == null) { return; } var encoding = TryGetEncoding(response.ContentEncoding, Encoding.UTF8); Result = await stream.ReadToEndAsync(encoding, token); } }; }
/// <summary> /// 获取构建输出 /// </summary> /// <param name="jobName"></param> /// <param name="buildNumber"></param> /// <returns></returns> public async Task <string> BuildOutput(string jobName, string buildNumber, string root = null) { if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } if (string.IsNullOrEmpty(buildNumber)) { throw new ArgumentException("'buildNumber' cannot be empty!"); } var url = NetPath.Combine(root, "job", jobName, buildNumber, "consoleText"); using (var response = await _httpClient.GetAsync(url)) { using (var content = response.Content) { using (var stream = await content.ReadAsStreamAsync()) { var encoding = TryGetEncoding(content, Encoding.UTF8); using (var reader = new StreamReader(stream, encoding)) { return(reader.ReadToEnd()); } } } } }
public QueueItemListCommand(IJenkinsContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Url = NetPath.Combine(context.BaseUrl, "queue/api/xml"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "GET"; }; OnRead = response => { using (var stream = response.GetResponseStream()) { if (stream == null) { return; } var document = XDocument.Load(stream); if (document.Root == null) { throw new ApplicationException("An empty response was returned!"); } Result = document.XPathSelectElements("/queue/item") .Select(node => new JenkinsQueueItem(node)).ToArray(); } }; }
public BuildProgressiveTextCommand(IJenkinsContext context, string jobName, string buildNumber, int start) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } if (string.IsNullOrEmpty(buildNumber)) { throw new ArgumentException("'buildNumber' cannot be empty!"); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, buildNumber, "logText/progressiveText"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWriteAsync = async(request) => { request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8"; using (var requestStream = await request.GetRequestStreamAsync()) using (var writer = new StreamWriter(requestStream)) { await writer.WriteAsync($"start={start}"); } }; OnReadAsync = async response => { var hSize = response.Headers["X-Text-Size"]; var hMoreData = response.Headers["X-More-Data"]; if (!int.TryParse(hSize, out var _size)) { throw new ApplicationException($"Unable to parse x-text-size header value '{hSize}'!"); } var _moreData = string.Equals(hMoreData, bool.TrueString, StringComparison.OrdinalIgnoreCase); Result = new JenkinsProgressiveTextResponse { Size = _size, MoreData = _moreData, }; using (var stream = response.GetResponseStream()) { if (stream == null) { return; } using (var reader = new StreamReader(stream)) { Result.Text = await reader.ReadToEndAsync(); } } }; }
public JobGetConfigCommand(IJenkinsContext context, string jobName) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("Value cannot be empty!", nameof(jobName)); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, "config.xml"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "GET"; }; OnReadAsync = async response => { var document = await ReadXmlAsync(response); Result = new JenkinsProject(document.Root); }; }
private void StartReceiver() { var httpConfig = agent.AgentConfiguration.Value.Http; var httpPrefix = $"http://{httpConfig.Host}:{httpConfig.Port}/"; if (!string.IsNullOrEmpty(httpConfig.Path)) { httpPrefix = NetPath.Combine(httpPrefix, httpConfig.Path); } if (!httpPrefix.EndsWith("/")) { httpPrefix += "/"; } receiver = new HttpReceiver(Context); receiver.Routes.Scan(Assembly.GetExecutingAssembly()); receiver.AddPrefix(httpPrefix); try { receiver.Start(); Log.Debug($"HTTP Server listening at {httpPrefix}"); } catch (Exception error) { Log.Error("Failed to start HTTP Receiver!", error); } }
private async Task UpdateLatest(string version) { var url = NetPath.Combine(UploadPath, ".version"); var request = (FtpWebRequest)WebRequest.Create(url); request.Method = WebRequestMethods.Ftp.DeleteFile; if (!string.IsNullOrEmpty(FtpUsername) || !string.IsNullOrEmpty(FtpPassword)) { request.Credentials = new NetworkCredential(FtpUsername, FtpPassword); } using (var _ = (FtpWebResponse)await request.GetResponseAsync()) { //... } //------------------ request = (FtpWebRequest)WebRequest.Create(url); request.Method = WebRequestMethods.Ftp.UploadFile; if (!string.IsNullOrEmpty(FtpUsername) || !string.IsNullOrEmpty(FtpPassword)) { request.Credentials = new NetworkCredential(FtpUsername, FtpPassword); } using (var stream = await request.GetRequestStreamAsync()) using (var writer = new StreamWriter(stream)) { writer.Write(version); } using (var _ = (FtpWebResponse)await request.GetResponseAsync()) { //... } }
private async Task <HttpAgentUpdateResultResponse> GetResult(PhotonServerDefinition server, string sessionId) { HttpClientEx client = null; try { var url = NetPath.Combine(server.Url, "api/agent/update/result"); client = HttpClientEx.Get(url, new { session = sessionId, }); await client.Send(); return(client.ParseJsonResponse <HttpAgentUpdateResultResponse>()); } catch (HttpStatusCodeException error) { if (error.HttpCode == HttpStatusCode.NotFound) { throw new ApplicationException($"Photon-Server instance '{server.Name}' not found!"); } throw; } finally { client?.Dispose(); } }
private async Task Reconnect(PhotonServerDefinition server, string latestVersion, TimeSpan timeout) { using (var tokenSource = new CancellationTokenSource(timeout)) using (var client = new WebClient()) { var token = tokenSource.Token; while (true) { token.ThrowIfCancellationRequested(); try { var url = NetPath.Combine(server.Url, "api/version"); var version = await client.DownloadStringTaskAsync(url); if (!VersionTools.HasUpdates(version, latestVersion)) { break; } } catch (Exception error) when(error is SocketException || error is WebException) { await Task.Delay(1000, tokenSource.Token); } } } }
/// <summary> /// Creates a full URL by joining <see cref="RootPath"/> and /// <paramref name="path"/>, with optional <paramref name="queryArgs"/>. /// </summary> public string GetRelative(string path, object queryArgs = null) { var url = NetPath.Combine(RootPath, path); if (queryArgs == null) { return(url); } var argList = ObjectExtensions.ToDictionary(queryArgs); var builder = new StringBuilder(); foreach (var arg in argList) { var eKey = HttpUtility.UrlEncode(arg.Key); var eValue = HttpUtility.UrlEncode(arg.Value?.ToString() ?? string.Empty); builder.Append(builder.Length > 0 ? "&" : "?"); builder.Append(eKey); builder.Append('='); builder.Append(eValue); } url += builder.ToString(); return(url); }
public JobDeleteCommand(IJenkinsContext context, string jobName) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, "doDelete"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "POST"; request.ContentLength = 0; request.AllowAutoRedirect = false; }; #if NET_ASYNC OnWriteAsync = async(request, token) => { request.Method = "POST"; request.ContentLength = 0; request.AllowAutoRedirect = false; }; #endif }
public CrumbGetCommand(IJenkinsContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Url = NetPath.Combine(context.BaseUrl, "crumbIssuer/api/xml"); UserName = context.UserName; Password = context.Password; OnWrite = request => { request.Method = "GET"; }; OnRead = response => { using (var stream = response.GetResponseStream()) { if (stream == null) { return; } var document = XDocument.Load(stream); if (document.Root == null) { throw new ApplicationException("An empty response was returned!"); } Result = new JenkinsCrumb(document.Root); } }; }
private async Task DownloadUpdate(HttpPackageIndex index) { if (!Directory.Exists(updateDirectory)) { Directory.CreateDirectory(updateDirectory); } try { var url = NetPath.Combine(Configuration.DownloadUrl, "CLI", index.Version, index.MsiFilename); using (var client = HttpClientEx.Get(url)) { await client.Send(); using (var fileStream = File.Open(updateFilename, FileMode.Create, FileAccess.Write)) using (var responseStream = client.ResponseBase.GetResponseStream()) { if (responseStream != null) { await responseStream.CopyToAsync(fileStream); } } } } catch (HttpStatusCodeException error) { throw new ApplicationException("Failed to download CLI update!", error); } }
public async Task <T> JobGet <T>(string jobName, string root = null) where T : class, IJenkinsJob { if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("Value cannot be empty!", nameof(jobName)); } string url = null; if (string.IsNullOrWhiteSpace(root)) { url = NetPath.Combine("job", jobName, "api/xml"); } else { if (root.StartsWith("job/") || root.StartsWith("/job/")) { url = NetPath.Combine(root, "job", jobName, "api/xml"); } else { url = NetPath.Combine("job", root, "job", jobName, "api/xml"); } } using (var response = await _httpClient.GetAsync(url)) { var document = await ReadXml(response); return(Activator.CreateInstance(typeof(T), document.Root) as T); } }
public async Task JobDelete(string jobName, string root = null) { if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } string url = null; if (string.IsNullOrWhiteSpace(root)) { url = NetPath.Combine("job", jobName, "doDelete"); } else { if (root.StartsWith("job/") || root.StartsWith("/job/")) { url = NetPath.Combine(root, "job", jobName, "doDelete"); } else { url = NetPath.Combine("job", root, "job", jobName, "doDelete"); } } using (var response = await _httpClient.PostAsync(url, null)) { } }
public JenkinsGetCommand(IJenkinsContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Url = NetPath.Combine(context.BaseUrl, "api/xml"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "GET"; }; OnRead = response => { var document = ReadXml(response); Result = new Jenkins(document.Root); }; #if NET_ASYNC OnWriteAsync = async(request, token) => { request.Method = "GET"; }; OnReadAsync = async(response, token) => { var document = await ReadXmlAsync(response); Result = new Jenkins(document.Root); }; #endif }
private void StartHttpServer() { var enableSecurity = ServerConfiguration.Value.Security?.Enabled ?? false; var http = ServerConfiguration.Value.Http; var contentDir = new ContentDirectory { DirectoryPath = Configuration.HttpContentDirectory, UrlPath = "/Content/", }; var sharedContentDir = new ContentDirectory { DirectoryPath = Configuration.HttpSharedContentDirectory, UrlPath = "/SharedContent/", }; var context = new HttpReceiverContext { ListenerPath = http.Path, ContentDirectories = { contentDir, sharedContentDir, }, }; if (enableSecurity) { var ldapAuth = new LdapAuthorization(); context.SecurityMgr = new ServerHttpSecurity { Authorization = ldapAuth, }; } context.Views.AddFolderFromExternal(Configuration.HttpViewDirectory); var httpPrefix = $"http://{http.Host}:{http.Port}/"; if (!string.IsNullOrEmpty(http.Path)) { httpPrefix = NetPath.Combine(httpPrefix, http.Path); } if (!httpPrefix.EndsWith("/")) { httpPrefix += "/"; } receiver = new HttpReceiver(context); receiver.Routes.Scan(Assembly.GetExecutingAssembly()); receiver.AddPrefix(httpPrefix); try { receiver.Start(); Log.Debug($"HTTP Server listening at {httpPrefix}"); } catch (Exception error) { Log.Error("Failed to start HTTP Receiver!", error); } }
public QueueGetItemCommand(IJenkinsContext context, int itemNumber) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Url = NetPath.Combine(context.BaseUrl, "queue/item", itemNumber.ToString(), "api/xml"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "POST"; }; OnRead = response => { using (var stream = response.GetResponseStream()) { if (stream == null) { return; } var document = XDocument.Load(stream); if (document.Root == null) { throw new ApplicationException("An empty response was returned!"); } Result = new JenkinsQueueItem(document.Root); } }; }
public JobGetCommand(IJenkinsContext context, string jobName) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("Value cannot be empty!", nameof(jobName)); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, "api/xml"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "GET"; }; OnReadAsync = async(response, token) => { var document = await ReadXmlAsync(response); Result = Activator.CreateInstance(typeof(T), document.Root) as T; }; }
public BuildGetCommand(IJenkinsContext context, string jobName, string buildNumber) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } if (string.IsNullOrEmpty(buildNumber)) { throw new ArgumentException("'buildNumber' cannot be empty!"); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, buildNumber, "api/xml"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "POST"; }; OnReadAsync = async(response, token) => { var document = await ReadXmlAsync(response); var args = new object[] { document.Root }; Result = Activator.CreateInstance(typeof(T), args) as T; }; }
public async Task Run(CommandContext context) { var server = context.Servers.Get(ServerName); var url = NetPath.Combine(server.Url, "api/log"); var request = WebRequest.CreateHttp(url); request.Method = "GET"; request.KeepAlive = false; using (var response = (HttpWebResponse)await request.GetResponseAsync()) using (var responseStream = response.GetResponseStream()) { if (responseStream == null) { return; } using (var reader = new StreamReader(responseStream)) { while (!reader.EndOfStream) { var line = await reader.ReadLineAsync(); Console.ResetColor(); Console.WriteLine(line); } } } }
public JobUpdateConfigurationCommand(IJenkinsContext context, string jobName, JenkinsProject job) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("Value cannot be empty!", nameof(jobName)); } if (job == null) { throw new ArgumentNullException(nameof(job)); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, "config.xml"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWriteAsync = async(request, token) => { request.Method = "POST"; request.ContentType = "application/xml"; await WriteXmlAsync(request, job.Node, token); }; }
private async Task BeginServerUpdate(PhotonServerDefinition server, HttpPackageIndex index) { ConsoleEx.Out.Write("Downloading Server update ", ConsoleColor.DarkCyan) .Write(index.Version, ConsoleColor.Cyan) .WriteLine("...", ConsoleColor.DarkCyan); var updateDirectory = Path.Combine(Configuration.Directory, "Updates"); var updateFilename = Path.Combine(updateDirectory, "Photon.Server.msi"); PathEx.CreatePath(updateDirectory); using (var client = new WebClient()) { var url = NetPath.Combine(Configuration.DownloadUrl, "server", index.Version, index.MsiFilename); await client.DownloadFileTaskAsync(url, updateFilename); } ConsoleEx.Out .WriteLine("Download Complete.", ConsoleColor.DarkBlue) .WriteLine("Uploading update to Server...", ConsoleColor.DarkCyan); await WebClientEx(server, client => { client.Method = "POST"; client.Url = NetPath.Combine(server.Url, "api/server/update"); client.ContentType = "application/octet-stream"; client.BodyFunc = () => File.Open(updateFilename, FileMode.Open, FileAccess.Read); }, null); ConsoleEx.Out.WriteLine("Upload Complete.", ConsoleColor.DarkBlue); }
private async Task UpdateLatest(string version, CancellationToken token) { var url = NetPath.Combine(UploadPath, ".version"); var request = (FtpWebRequest)WebRequest.Create(url); request.Method = WebRequestMethods.Ftp.DeleteFile; if (!string.IsNullOrEmpty(FtpUsername) || !string.IsNullOrEmpty(FtpPassword)) { request.Credentials = new NetworkCredential(FtpUsername, FtpPassword); } using (token.Register(() => request.Abort())) using (await request.GetResponseAsync()) {} //------------------ var request2 = (FtpWebRequest)WebRequest.Create(url); request2.Method = WebRequestMethods.Ftp.UploadFile; if (!string.IsNullOrEmpty(FtpUsername) || !string.IsNullOrEmpty(FtpPassword)) { request2.Credentials = new NetworkCredential(FtpUsername, FtpPassword); } using (token.Register(() => request.Abort())) { using (var stream = await request2.GetRequestStreamAsync()) using (var writer = new StreamWriter(stream)) { writer.Write(version); } using (await request2.GetResponseAsync()) {} } }
public JobBuildCommand(IJenkinsContext context, string jobName) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } Url = NetPath.Combine(context.BaseUrl, "job", jobName, "build?delay=0sec"); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "POST"; }; OnRead = response => { if (response.StatusCode != System.Net.HttpStatusCode.Created) { throw new JenkinsJobBuildException($"Expected HTTP status code 201 but found {(int)response.StatusCode}!"); } Result = new JenkinsBuildResult { QueueItemUrl = response.GetResponseHeader("Location") }; }; }
public static async Task <HttpPackageIndex> GetLatestCliIndex() { using (var webClient = new WebClient()) { var indexUrl = NetPath.Combine(ServerUrl, "api/cli/index"); var json = await webClient.DownloadStringTaskAsync(indexUrl); return(JsonConvert.DeserializeObject <HttpPackageIndex>(json)); } }
public async Task JobCreate(string jobName, JenkinsProject job, string root = null) { if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("Value cannot be empty!", nameof(jobName)); } if (job == null) { throw new ArgumentNullException(nameof(job)); } string url = null; if (string.IsNullOrWhiteSpace(root)) { url = NetPath.Combine("createItem") + NetPath.Query(new { name = jobName }); } else { if (root.StartsWith("job/") || root.StartsWith("/job/")) { url = NetPath.Combine(root, "createItem") + NetPath.Query(new { name = jobName }); } else { url = NetPath.Combine("job", root, "createItem") + NetPath.Query(new { name = jobName }); } } var xmlSettings = new XmlWriterSettings { ConformanceLevel = ConformanceLevel.Fragment, Indent = false, }; var contentData = ""; using (var sw = new StringWriter()) { using (var writer = XmlWriter.Create(sw, xmlSettings)) { job.Node.WriteTo(writer); } contentData = sw.ToString(); } using (var response = await _httpClient.PostAsync(url, new StringContent(contentData, Encoding.UTF8, "application/xml"))) { if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) { await JobUpdate(jobName, job, root); } } }
public async Task <Jenkins> JenkinsGet(string root = null) { var url = NetPath.Combine(root, "api/xml"); using (var response = await _httpClient.GetAsync("api/xml")) { var document = await ReadXml(response); return(new Jenkins(document.Root)); } }
public ArtifactGetCommand(IJenkinsContext context, string jobName, string buildNumber, string filename) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } if (string.IsNullOrEmpty(buildNumber)) { throw new ArgumentException("'buildNumber' cannot be empty!"); } if (string.IsNullOrEmpty(filename)) { throw new ArgumentException("'filename' cannot be empty!"); } var urlFilename = filename.Replace('\\', '/'); Url = NetPath.Combine(context.BaseUrl, "job", jobName, buildNumber, "artifact", urlFilename); UserName = context.UserName; Password = context.Password; Crumb = context.Crumb; OnWrite = request => { request.Method = "POST"; }; OnRead = response => { using (var stream = response.GetResponseStream()) { if (stream == null) { return; } try { Result = new MemoryStream(); stream.CopyTo(Result); Result.Seek(0, SeekOrigin.Begin); } catch { Result?.Dispose(); throw; } } }; }
public async Task <JenkinsBuildResult> JobBuildWithParameters(string jobName, IDictionary <string, string> jobParameters, string root = null) { if (string.IsNullOrEmpty(jobName)) { throw new ArgumentException("'jobName' cannot be empty!"); } if (jobParameters == null) { throw new ArgumentNullException(nameof(jobParameters)); } var _params = new Dictionary <string, string>(jobParameters) { ["delay"] = "0sec", }; var query = new StringWriter(); WriteJobParameters(query, _params); string url = null; if (string.IsNullOrWhiteSpace(root)) { url = NetPath.Combine("job", jobName, $"buildWithParameters?{query}"); } else { if (root.StartsWith("job/") || root.StartsWith("/job/")) { url = NetPath.Combine(root, "job", jobName, $"buildWithParameters?{query}"); } else { url = NetPath.Combine("job", root, "job", jobName, $"buildWithParameters?{query}"); } } using (var response = await _httpClient.PostAsync(url, null)) { if (response.StatusCode != System.Net.HttpStatusCode.Created) { throw new JenkinsJobBuildException($"Expected HTTP status code 201 but found {(int)response.StatusCode}!"); } return(new JenkinsBuildResult { QueueItemUrl = response.Headers.Location.AbsoluteUri }); } }