bool IsBranchProtected(DBLane lane) { if (!lane.repository.Contains("github")) return false; var repo = ParseRepo(lane.repository); var branch = ParseBranch(lane.max_revision); var key = repo + ":" + branch; var token = Session["github_token"]; var url = "https://api.github.com/repos/" + repo + "/branches/" + branch + "/protection"; var client = WebRequest.Create(url) as HttpWebRequest; client.Accept = "application/vnd.github.loki-preview+json"; client.ContentType = "application/json"; client.Method = WebRequestMethods.Http.Get; client.PreAuthenticate = true; client.UserAgent = "app"; client.Headers.Add("Authorization", "token " + token); if (protectedBranches.ContainsKey(key)) client.Headers.Add("If-None-Match", protectedBranches[key]); try { var resp = client.GetResponse() as HttpWebResponse; if (resp.Headers.AllKeys.Contains("Etag")) protectedBranches.Add(key, resp.Headers["Etag"]); return resp.StatusCode == HttpStatusCode.OK || resp.StatusCode == HttpStatusCode.NotModified; } catch (WebException) { return false; } }
bool CheckCmdExists (DBLane lane, string cmd_name) { var res = ws.GetLaneForEdit (login, lane.id, null); var cmd = (from c in res.Commands where c.command == cmd_name select c).FirstOrDefault (); if (cmd != null) Console.WriteLine ("Step '" + cmd_name + "' already exists in lane '" + lane.lane + "'"); return cmd == null; }
void PrintLaneTree (Dictionary<DBLane, List<DBLane>> tree, DBLane lane, int level) { for (int i = 0; i < level; ++i) Console.Write (' '); Console.WriteLine (lane.lane); foreach (var l in tree [lane]) PrintLaneTree (tree, l, level + 1); }
DBCommand FindCmdByName (DBLane lane, string cmd_name) { var res = ws.GetLaneForEdit (login, lane.id, null); var cmd = (from c in res.Commands where c.command == cmd_name select c).FirstOrDefault (); if (cmd == null) Console.WriteLine ("Step '" + cmd_name + "' not found in lane '" + lane.lane + "'"); return cmd; }
/// <summary> /// /// </summary> /// <param name="db"></param> /// <param name="lane"></param> /// <param name="host"></param> /// <param name="limit"></param> /// <param name="page">First page = 0, second page = 1, etc.</param> /// <returns></returns> public static List<DBRevisionWorkView> Query (DB db, DBLane lane, DBHost host, int limit, int page) { Console.WriteLine ("Query {0} {1} {2} {3}", lane, host, limit, page); List<DBRevisionWorkView> result = new List<DBRevisionWorkView> (); using (IDbTransaction transaction = db.BeginTransaction ()) { using (IDbCommand cmd = db.CreateCommand ()) { // copy&paste from CustomTypes.sql cmd.CommandText = @" SELECT RevisionWork.id, Revision.revision INTO TEMP revisionwork_temptable FROM RevisionWork INNER JOIN Revision on RevisionWork.revision_id = Revision.id WHERE RevisionWork.lane_id = @lane_id AND RevisionWork.host_id = @host_id ORDER BY Revision.date DESC LIMIT @limit OFFSET @offset; -- For some reason postgresql thinks the temp table has 1230 entries, while it usually has about 20 entries, -- and decides to do a sequential scan on the work tabe. Analyze it to make it realize its untrue presumptions. ANALYZE revisionwork_temptable; SELECT Work.id, Work.command_id, Work.state, Work.starttime, Work.endtime, Work.duration, Work.logfile, Work.summary, Host.host, Lane.lane, Revision.author, Revision.revision, Command.command, Command.nonfatal, Command.alwaysexecute, Command.sequence, Command.internal, RevisionWork.lane_id, RevisionWork.host_id, RevisionWork.revision_id, RevisionWork.state AS revisionwork_state, WorkHost.host AS workhost FROM Work INNER JOIN RevisionWork ON Work.revisionwork_id = RevisionWork.id INNER JOIN Revision ON RevisionWork.revision_id = Revision.id INNER JOIN Lane ON RevisionWork.lane_id = Lane.id INNER JOIN Host ON RevisionWork.host_id = Host.id LEFT JOIN Host AS WorkHost ON RevisionWork.workhost_id = WorkHost.id INNER JOIN Command ON Work.command_id = Command.id WHERE Work.revisionwork_id IN (SELECT id FROM revisionwork_temptable) ORDER BY Revision.date DESC; "; DB.CreateParameter (cmd, "lane_id", lane.id); DB.CreateParameter (cmd, "host_id", host.id); DB.CreateParameter (cmd, "limit", limit); DB.CreateParameter (cmd, "offset", page * limit); using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) { result.Add (new DBRevisionWorkView (reader)); } } } return result; } }
public LaneTreeNode (DBLane lane, IEnumerable<DBHostLane> hostlanes){ this.Lane = lane; if (hostlanes != null && lane != null) { foreach (DBHostLane hl in hostlanes) { if (hl.lane_id != lane.id) continue; HostLanes.Add (hl); } } }
public string GenerateHeader (GetViewWorkTableDataResponse response, DBLane lane, DBHost host, DBCommand command) { if (!Authentication.IsInRole (response, MonkeyWrench.DataClasses.Logic.Roles.Administrator)) { return string.Format (@" <h2>Step {4} on lane '{2}' on '{3}' (<a href='ViewTable.aspx?lane_id={0}&host_id={1}'>table</a>)</h2><br/>", lane.id, host.id, lane.lane, host.host, command.command); } else { return string.Format (@" <h2>Step {4} on lane '<a href='EditLane.aspx?lane_id={0}'>{2}</a>' on '<a href='EditHost.aspx?host_id={1}'>{3}</a>' (<a href='ViewTable.aspx?lane_id={0}&host_id={1}'>table</a>)</h2><br/>", lane.id, host.id, lane.lane, host.host, command.command); } }
public static List<DBLaneDeletionDirectiveView> Find (DB db, DBLane lane) { List<DBLaneDeletionDirectiveView> result = new List<DBLaneDeletionDirectiveView> (); using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = @"SELECT * FROM LaneDeletionDirectiveView WHERE lane_id = @lane_id"; DB.CreateParameter (cmd, "lane_id", lane.id); using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) result.Add (new DBLaneDeletionDirectiveView (reader)); } } return result; }
/// <summary> /// Returns a list of all the dependencies for the specified lane. /// Returns null if there are no dependencies for the lane. /// </summary> /// <param name="lane"></param> /// <returns></returns> public static List<DBLaneDependency> GetDependencies (DB db, DBLane lane) { List<DBLaneDependency> result = null; using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = "SELECT * FROM LaneDependency"; if (lane != null) { cmd.CommandText += " WHERE lane_id = @lane_id"; DB.CreateParameter (cmd, "lane_id", lane.id); } cmd.CommandText += ";"; using (IDataReader reader = cmd.ExecuteReader ()) { while (reader.Read ()) { if (result == null) result = new List<DBLaneDependency> (); result.Add (new DBLaneDependency (reader)); } } } return result; }
public FindRevisionResponse FindRevisionByHash(WebServiceLogin login, DBLane lane, string revision) { FindRevisionResponse response = new FindRevisionResponse (); using (DB db = new DB ()) { Authenticate (db, login, response); response.Revision = FindRevision (db, lane, revision); } return response; }
public static string GenerateHeader (GetViewLaneDataResponse response, DBLane lane, DBHost host, DBRevision revision, string description) { if (!Authentication.IsInRole (response, MonkeyWrench.DataClasses.Logic.Roles.Administrator)) { return string.Format (@" <h2>{4} revision <a href='ViewLane.aspx?lane_id={0}&host_id={1}&revision_id={6}'>{5}</a> on lane '{2}' on '<a href='ViewHostHistory.aspx?host_id={1}'>{3}</a>' (<a href='ViewTable.aspx?lane_id={0}&host_id={1}'>table</a>)</h2><br/>", lane.id, host.id, lane.lane, host.host, description, revision.revision, revision.id); } else { return string.Format (@" <h2>{4} revision <a href='ViewLane.aspx?lane_id={0}&host_id={1}&revision_id={6}'>{5}</a> on lane '<a href='EditLane.aspx?lane_id={0}'>{2}</a>' on '<a href='ViewHostHistory.aspx?host_id={1}'>{3}</a>' (<a href='ViewTable.aspx?lane_id={0}&host_id={1}'>table</a>)</h2><br/>", lane.id, host.id, lane.lane, host.host, description, revision.revision, revision.id); } }
public static void FindPeopleForCommit (DBLane lane, DBRevision revision, List<DBPerson> people) { DBPerson person; try { foreach (string repository in lane.repository.Split (new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { string cache_dir = Configuration.GetSchedulerRepositoryCacheDirectory (repository); if (!Directory.Exists (cache_dir)) continue; using (Process git = new Process ()) { DateTime git_start = DateTime.Now; git.StartInfo.FileName = "git"; git.StartInfo.Arguments = "log -1 --pretty=format:'%aE%n%aN%n%cE%n%cN' " + revision.revision; git.StartInfo.WorkingDirectory = cache_dir; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardOutput = true; git.Start (); string author_email = git.StandardOutput.ReadLine (); string author_name = git.StandardOutput.ReadLine (); string committer_email = git.StandardOutput.ReadLine (); string committer_name = git.StandardOutput.ReadLine (); // Wait 10 minutes for git to finish, otherwise abort. if (!git.WaitForExit (1000 * 60 * 10)) { GITUpdater.log.Error ("Getting commit info took more than 10 minutes, aborting."); try { git.Kill (); git.WaitForExit (10000); // Give the process 10 more seconds to completely exit. } catch (Exception ex) { GITUpdater.log.ErrorFormat ("Aborting commit info retrieval failed: {0}", ex.ToString ()); } } if (git.HasExited && git.ExitCode == 0) { GITUpdater.log.InfoFormat ("Got commit info successfully in {0} seconds", (DateTime.Now - git_start).TotalSeconds); person = new DBPerson (); person.fullname = author_name; person.Emails = new string [] { author_email }; people.Add (person); if (author_name != committer_name && !string.IsNullOrEmpty (committer_name)) { person = new DBPerson (); person.fullname = committer_name; person.Emails = new string [] {committer_email}; people.Add (person); } GITUpdater.log.DebugFormat ("Git commit info for {0}: author_name = {1} author_email: {2} committer_name: {3} committer_email: {4}", revision.revision, author_name, author_email, committer_name, committer_email); } else { GITUpdater.log.ErrorFormat ("Didn't get commit info, HasExited: {0}, ExitCode: {1}", git.HasExited, git.HasExited ? git.ExitCode.ToString () : "N/A"); } } } } catch (Exception ex) { GITUpdater.log.ErrorFormat ("Exception while trying to get commit info: {0}", ex.ToString ()); } }
private List<GitEntry> GetGITLog (DBLane dblane, string repository, string min_revision, string max_revision) { List<GitEntry> result = null; try { GITUpdater.log.InfoFormat ("Retrieving log for '{0}', repository: '{1}', min_revision: {2} max_revision: {3}", dblane.lane, repository, min_revision, max_revision); // Updating the repository cache string cache_dir = Configuration.GetSchedulerRepositoryCacheDirectory (repository); if (!Directory.Exists (cache_dir)) Directory.CreateDirectory (cache_dir); // Download/update the cache using (Process git = new Process ()) { DateTime git_start = DateTime.Now; if (fetched_directories.Contains (repository)) { GITUpdater.log.DebugFormat ("Not fetching repository '{0}', it has already been fetched in this run", repository); } else { git.StartInfo.FileName = "git"; if (!Directory.Exists (Path.Combine (cache_dir, ".git"))) { git.StartInfo.Arguments = "clone -q --no-checkout " + repository + " ."; } else { git.StartInfo.Arguments = "fetch"; } git.StartInfo.WorkingDirectory = cache_dir; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardOutput = true; git.StartInfo.RedirectStandardError = true; git.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8; git.StartInfo.StandardErrorEncoding = System.Text.Encoding.UTF8; GITUpdater.log.DebugFormat ("Executing: '{0} {1}' in {2}", git.StartInfo.FileName, git.StartInfo.Arguments, cache_dir); git.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e) { if (e.Data == null) return; GITUpdater.log.DebugFormat ("FETCH: {0}", e.Data); }; git.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs e) { if (e.Data == null) return; GITUpdater.log.WarnFormat ("FETCH STDERR: {0}", e.Data); }; git.Start (); git.BeginOutputReadLine (); git.BeginErrorReadLine (); if (!git.WaitForExit (1000 * 60 * 10 /* 10 minutes */)) { GITUpdater.log.ErrorFormat ("Could not fetch repository, git didn't finish in 10 minutes."); return null; } if (!git.HasExited || git.ExitCode != 0) { GITUpdater.log.ErrorFormat ("Could not fetch repository, HasExited: {0}, ExitCode: {1}", git.HasExited, git.HasExited ? git.ExitCode.ToString () : "N/A"); return null; } fetched_directories.Add (repository); GITUpdater.log.InfoFormat ("Fetched git repository in {0} seconds", (DateTime.Now - git_start).TotalSeconds); } } string range = string.Empty; if (string.IsNullOrEmpty (min_revision)) { range = max_revision; } else { range = min_revision + "^.." + max_revision; } using (Process git = new Process ()) { DateTime git_start = DateTime.Now; git.StartInfo.FileName = "git"; // --reverse: git normally gives commits in newest -> oldest, we want to add them to the db in the reverse order git.StartInfo.Arguments = "rev-list --reverse --header "; if (!dblane.traverse_merge) git.StartInfo.Arguments += "--first-parent "; git.StartInfo.Arguments += range; GITUpdater.log.DebugFormat ("Executing: '{0} {1}' in {2}", git.StartInfo.FileName, git.StartInfo.Arguments, cache_dir); git.StartInfo.WorkingDirectory = cache_dir; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardOutput = true; git.StartInfo.RedirectStandardError = true; git.StartInfo.WorkingDirectory = cache_dir; Thread stdout = new Thread (delegate () { StringBuilder builder = new StringBuilder (); GitEntry current = new GitEntry (); bool in_header = true; bool done = false; while (!done) { int ch = 0; if (git.StandardOutput.EndOfStream) { done = true; } else { ch = git.StandardOutput.Read (); } if (ch == 0) { /* end of record */ if (result == null) result = new List<GitEntry> (); result.Add (current); current = new GitEntry (); in_header = true; builder.Length = 0; } else if (in_header && ch == '\n') { /* end of header line */ if (builder.Length == 0) { /* entering log message */ in_header = false; } else { string header = builder.ToString (); if (current.revision == null) { current.revision = header; } else if (header.StartsWith ("author ")) { header = header.Substring ("author ".Length, header.IndexOf ('<') - "author ".Length - 1); current.author = header; } else if (header.StartsWith ("committer ")) { header = header.Substring ("committer ".Length); int gt = header.LastIndexOf ('>'); if (gt > 0) { current.timestamp = header.Substring (gt + 1).Trim (); current.timestamp = current.timestamp.Substring (0, current.timestamp.IndexOf (' ')).Trim (); } else { GITUpdater.log.Warn ("Could not find timestamp in committer line"); } } else { // do nothing } } builder.Length = 0; } else { builder.Append ((char) ch); } } }); var stderr_output = new StringBuilder (); Thread stderr = new Thread (delegate () { string line; while (null != (line = git.StandardError.ReadLine ())) { stderr_output.AppendLine (line); } }); git.Start (); stdout.Start (); stderr.Start (); // Wait 10 minutes for git to finish, otherwise abort. if (!git.WaitForExit (1000 * 60 * 10)) { GITUpdater.log.ErrorFormat ("Getting log took more than 10 minutes, aborting."); try { git.Kill (); git.WaitForExit (10000); // Give the process 10 more seconds to completely exit. } catch (Exception ex) { GITUpdater.log.ErrorFormat ("Aborting log retrieval failed: {0}", ex.ToString ()); } } stdout.Join ((int) TimeSpan.FromMinutes (1).TotalMilliseconds); stderr.Join ((int) TimeSpan.FromMinutes (1).TotalMilliseconds); if (git.HasExited && git.ExitCode == 0) { GITUpdater.log.InfoFormat ("Got log successfully in {0} seconds", (DateTime.Now - git_start).TotalSeconds); return result; } else { GITUpdater.log.ErrorFormat ("Couldn't get git log for lane {0} repository {1}. HasExited: {2} ExitCode: {3} StandardError: \n{4}", dblane.lane, repository, git.HasExited, git.HasExited ? git.ExitCode.ToString () : "N/A", stderr_output.ToString ()); return null; } } } catch (Exception ex) { GITUpdater.log.ErrorFormat ("Exception while trying to get git log: {0}", ex); return null; } }
protected override void OnInit (EventArgs e) { base.OnInit (e); try { TableRow row; GetLaneForEditResponse response; txtID.Attributes ["readonly"] = "readonly"; string action = Request ["action"]; string command_id = Request ["command_id"]; int id; int sequence; int timeout; tblCommands.Visible = true; tblFiles.Visible = true; int.TryParse (Request ["lane_id"], out id); response = Master.WebService.GetLaneForEdit (Master.WebServiceLogin, id, Request ["lane"]); lane = response.Lane; if (lane == null) { Response.Redirect ("EditLanes.aspx", false); return; } lblH2.Text = "Lane: " + lane.lane; lblDeletionDirectiveErrors.Visible = false; // find possible parent lanes lstParentLane.Items.Clear (); lstParentLane.Items.Add (new ListItem ("None", "0")); foreach (DBLane l in response.Lanes) { if (l.id == lane.id) continue; if (Utils.IsDescendentLaneOf (response.Lanes, lane, l, 0)) continue; // our descendents can't be our parents too. lstParentLane.Items.Add (new ListItem (l.lane, l.id.ToString ())); if (!IsPostBack) { if (lane.parent_lane_id.HasValue && lane.parent_lane_id.Value == l.id) lstParentLane.SelectedIndex = lstParentLane.Items.Count - 1; } } if (!IsPostBack) { for (int i = 0; i < cmbSourceControl.Items.Count; i++) { cmbSourceControl.Items [i].Selected = lane.source_control == cmbSourceControl.Items [i].Text; } txtRepository.Text = lane.repository; txtCommitFilter.Text = lane.commit_filter; txtMinRevision.Text = lane.min_revision; txtMaxRevision.Text = lane.max_revision; txtLane.Text = lane.lane; txtID.Text = lane.id.ToString (); // find (direct) child lanes foreach (DBLane l in response.Lanes) { if (l.parent_lane_id.HasValue && l.parent_lane_id.Value == lane.id) { if (!string.IsNullOrEmpty (lblChildLanes.Text)) lblChildLanes.Text += ", "; lblChildLanes.Text += l.lane; } } } if (!string.IsNullOrEmpty (action)) { switch (action) { case "createFile": Master.WebService.CreateLanefile (Master.WebServiceLogin, lane.id, Request ["filename"]); break; case "addFile": if (int.TryParse (Request ["lanefile_id"], out id)) Master.WebService.AttachFileToLane (Master.WebServiceLogin, lane.id, id); break; case "deleteFile": if (int.TryParse (Request ["file_id"], out id)) Master.WebService.DeattachFileFromLane (Master.WebServiceLogin, lane.id, id); break; case "editCommandFilename": if (int.TryParse (command_id, out id)) Master.WebService.EditCommandFilename (Master.WebServiceLogin, id, Request ["filename"]); break; case "editCommandSequence": if (int.TryParse (command_id, out id)) { if (int.TryParse (Request ["sequence"], out sequence)) Master.WebService.EditCommandSequence (Master.WebServiceLogin, id, sequence); } break; case "editCommandArguments": if (int.TryParse (command_id, out id)) Master.WebService.EditCommandArguments (Master.WebServiceLogin, id, Request ["arguments"]); break; case "editCommandTimeout": if (int.TryParse (command_id, out id)) { if (int.TryParse (Request ["timeout"], out timeout)) Master.WebService.EditCommandTimeout (Master.WebServiceLogin, id, timeout); } break; case "editCommandWorkingDirectory": if (int.TryParse (command_id, out id)) Master.WebService.EditCommandWorkingDirectory (Master.WebServiceLogin, id, Request ["working_directory"]); break; case "editCommandUploadFiles": if (int.TryParse (command_id, out id)) Master.WebService.EditCommandUploadFiles (Master.WebServiceLogin, id, Request ["upload_files"]); break; case "deletecommand": if (int.TryParse (command_id, out id)) Master.WebService.DeleteCommand (Master.WebServiceLogin, id); break; case "switchNonFatal": if (int.TryParse (command_id, out id)) Master.WebService.SwitchCommandNonFatal (Master.WebServiceLogin, id); break; case "switchAlwaysExecute": if (int.TryParse (command_id, out id)) Master.WebService.SwitchCommandAlwaysExecute (Master.WebServiceLogin, id); break; case "switchInternal": if (int.TryParse (command_id, out id)) Master.WebService.SwitchCommandInternal (Master.WebServiceLogin, id); break; case "addCommand": if (!int.TryParse (Request ["sequence"], out sequence)) sequence = -1; Master.WebService.AddCommand (Master.WebServiceLogin, lane.id, Request ["command"], false, false, 60, sequence); break; case "switchHostEnabled": if (int.TryParse (Request ["host_id"], out id)) Master.WebService.SwitchHostEnabledForLane (Master.WebServiceLogin, lane.id, id); break; case "removeHost": if (int.TryParse (Request ["host_id"], out id)) Master.WebService.RemoveHostForLane (Master.WebServiceLogin, lane.id, id); break; case "addHost": if (int.TryParse (Request ["host_id"], out id)) Master.WebService.AddHostToLane (Master.WebServiceLogin, lane.id, id); break; case "addDependency": if (int.TryParse (Request ["dependent_lane_id"], out id)) { int condition; int host_id; if (int.TryParse (Request ["condition"], out condition)) { if (int.TryParse (Request ["dependent_host_id"], out host_id)) { Master.WebService.AddDependencyToLane (Master.WebServiceLogin, lane.id, id, host_id > 0 ? (Nullable<int>) host_id : (Nullable<int>) null, (DBLaneDependencyCondition) condition); } } } break; case "editDependencyFilename": if (int.TryParse (Request ["lanedependency_id"], out id)) Master.WebService.EditLaneDependencyFilename (Master.WebServiceLogin, id, Request ["filename"]); break; case "deleteDependency": if (int.TryParse (Request ["dependency_id"], out id)) Master.WebService.DeleteLaneDependency (Master.WebServiceLogin, id); break; case "editDependencyDownloads": if (int.TryParse (Request ["lanedependency_id"], out id)) Master.WebService.EditLaneDependencyDownloads (Master.WebServiceLogin, id, Request ["downloads"]); break; case "editEnvironmentVariableValue": { int host_id, lane_id; if (int.TryParse (Request ["host_id"], out host_id)) if (int.TryParse (Request ["lane_id"], out lane_id)) { if (int.TryParse (Request ["id"], out id)) { DBEnvironmentVariable ev = new DBEnvironmentVariable (); ev.id = id; ev.host_id = host_id == 0 ? (int?)null : host_id; ev.lane_id = lane_id == 0 ? (int?)null : lane_id; ev.name = Request ["name"]; ev.value = Request ["value"]; Master.WebService.EditEnvironmentVariable (Master.WebServiceLogin, ev); } } } break; default: break; } RedirectToSelf (); } // Files foreach (DBLanefile file in response.Files) { string text = file.name; if (!string.IsNullOrEmpty (file.mime)) text += " (" + file.mime + ")"; tblFiles.Rows.Add (Utils.CreateTableRow ( string.Format ("<a href='EditLaneFile.aspx?lane_id={1}&file_id={0}'>{2}</a>", file.id, lane.id, file.name), file.mime, string.Format ("<a href='EditLane.aspx?lane_id={1}&action=deleteFile&file_id={0}'>Delete</a> <a href='ViewLaneFileHistory.aspx?id={0}'>View history</a>", file.id, lane.id))); } tblFiles.Rows.Add (Utils.CreateTableRow ( "<input type='text' value='filename' id='txtCreateFileName'></input>", "text/plain", string.Format ("<a href='javascript:createFile ({0})'>Add</a>", lane.id) )); StringBuilder existing_files = new StringBuilder (); existing_files.AppendLine ("<select id='cmbExistingFiles'>"); foreach (DBLanefile file in response.ExistingFiles) { existing_files.AppendFormat ("<option value='{1}'>{0}</option>\n", file.name, file.id); } existing_files.AppendLine ("</select>"); tblFiles.Rows.Add (Utils.CreateTableRow ( existing_files.ToString (), "N/A", string.Format ("<a href='javascript:addFile ({0})'>Add</a>", lane.id) )); tblFiles.Visible = true; // commands foreach (DBCommand command in response.Commands) { string filename = command.command; DBLanefile file = Utils.FindFile (response.Files, f => f.name == filename); if (file != null) filename = string.Format ("<a href='EditLaneFile.aspx?lane_id={1}&file_id={0}'>{2}</a>", file.id, lane.id, file.name); string working_directory = "<em>modify</em>"; if (!string.IsNullOrEmpty(command.working_directory)) working_directory = command.working_directory; string upload_files = "<em>modify</em>"; if (!string.IsNullOrEmpty(command.upload_files)) upload_files = command.upload_files; tblCommands.Rows.Add (Utils.CreateTableRow ( string.Format ("<a href='javascript:editCommandSequence ({2}, {0}, true, \"{1}\")'>{1}</a>", command.id, command.sequence, lane.id), filename, string.Format ("<a href='EditLane.aspx?lane_id={0}&command_id={3}&action=switchAlwaysExecute'>{2}</a>", lane.id, (!command.alwaysexecute).ToString (), command.alwaysexecute ? "yes" : "no", command.id), string.Format ("<a href='EditLane.aspx?lane_id={0}&command_id={3}&action=switchNonFatal'>{2}</a>", lane.id, (!command.nonfatal).ToString (), command.nonfatal ? "yes" : "no", command.id), string.Format ("<a href='EditLane.aspx?lane_id={0}&command_id={1}&action=switchInternal'>{2}</a>", lane.id, command.id, (command.@internal ? "yes" : "no")), string.Format ("<a href='javascript:editCommandFilename ({2}, {0}, true, \"{1}\")'>{1}</a>", command.id, command.filename, lane.id), string.Format ("<a href='javascript:editCommandArguments ({2}, {0}, true, \"{1}\")'>{3}</a>", command.id, command.arguments.Replace ("\"", "\\\""), lane.id, command.arguments), string.Format ("<a href='javascript:editCommandTimeout ({2}, {0}, true, \"{1}\")'>{1} minutes</a>", command.id, command.timeout, lane.id), string.Format ("<a href='javascript:editCommandWorkingDirectory ({2}, {0}, true, \"{1}\")'>{3}</a>", command.id, command.working_directory, lane.id, working_directory), string.Format ("<a href='javascript:editCommandUploadFiles ({2}, {0}, true, \"{1}\")'>{3}</a>", command.id, command.upload_files, lane.id, upload_files), string.Format ("<a href='EditLane.aspx?lane_id={0}&action=deletecommand&command_id={1}'>Delete</a>", lane.id, command.id))); } tblCommands.Rows.Add (Utils.CreateTableRow ( (response.Commands.Count * 10).ToString (), string.Format ("<input type='text' value='command' id='txtCreateCommand_name'></input>"), "no", "no", "no", "bash", "-ex {0}", "60 minutes", "-", "-", string.Format ("<a href='javascript:addCommand ({0}, {1})'>Add</a>", lane.id, (response.Commands.Count * 10)))); // Show all the hosts List<string> current_hosts = new List<string> (); string html; foreach (DBHostLaneView view in response.HostLaneViews) { string ed = view.enabled ? "enabled" : "disabled"; row = new TableRow (); row.Cells.Add (Utils.CreateTableCell (string.Format ("<a href='EditHost.aspx?host_id={0}'>{1}</a>", view.host_id, view.host), view.enabled ? "enabled" : "disabled")); html = string.Format ("<a href='EditLane.aspx?lane_id={0}&host_id={1}&action=removeHost'>Remove</a> ", lane.id, view.host_id); html = html + string.Format ("<a href='EditLane.aspx?lane_id={0}&host_id={1}&action=switchHostEnabled'>{2}</a>", lane.id, view.host_id, (view.enabled ? "Disable" : "Enable")); row.Cells.Add (Utils.CreateTableCell (html, ed)); tblHosts.Rows.Add (row); current_hosts.Add (view.host); } if (response.Hosts.Count != current_hosts.Count) { row = new TableRow (); html = "<select id='lstHosts'>"; foreach (DBHost host in response.Hosts) { if (!current_hosts.Contains (host.host)) html += "<option value='" + host.id + "'>" + host.host + "</option>"; } html += "</select>"; row.Cells.Add (Utils.CreateTableCell (html)); row.Cells.Add (Utils.CreateTableCell (string.Format ("<a href='javascript:addHost({0})'>Add</a>", lane.id))); tblHosts.Rows.Add (row); } // dependencies foreach (DBLaneDependency dependency in response.Dependencies) { row = new TableRow (); for (int i = 0; i < response.Lanes.Count; i++) { if (response.Lanes [i].id == dependency.dependent_lane_id) { row.Cells.Add (Utils.CreateTableCell (response.Lanes [i].lane)); break; } } row.Cells.Add (Utils.CreateTableCell (dependency.Condition.ToString ())); row.Cells.Add (Utils.CreateTableCell (dependency.dependent_host_id.HasValue ? Utils.FindHost (response.Hosts, dependency.dependent_host_id.Value).host : "Any")); switch (dependency.Condition) { case DBLaneDependencyCondition.DependentLaneSuccessWithFile: row.Cells.Add (Utils.CreateTableCell (string.Format ("<a href='javascript: editDependencyFilename ({0}, {1}, \"{2}\")'>{2}</a>", lane.id, dependency.id, string.IsNullOrEmpty (dependency.filename) ? "(edit)" : dependency.filename))); break; case DBLaneDependencyCondition.DependentLaneSuccess: default: row.Cells.Add (Utils.CreateTableCell ("-")); break; } row.Cells.Add (Utils.CreateTableCell (string.Format ("<a href='javascript: editDependencyDownloads ({0}, {1}, \"{2}\")'>{3}</a>", lane.id, dependency.id, string.IsNullOrEmpty (dependency.download_files) ? string.Empty : dependency.download_files.Replace ("\"", "\\\""), string.IsNullOrEmpty (dependency.download_files) ? "(edit)" : HttpUtility.HtmlEncode (dependency.download_files)))); row.Cells.Add (Utils.CreateTableCell (string.Format ("<a href='javascript: deleteDependency ({0}, {1})'>Delete</a>", lane.id, dependency.id))); tblDependencies.Rows.Add (row); } // Create new dependency row row = new TableRow (); html = "<select id='lstDependentLanes'>"; foreach (DBLane l in response.Lanes) { if (l.id == lane.id) continue; html += string.Format ("<option value='{0}'>{1}</option>", l.id, l.lane); } html += "</select>"; row.Cells.Add (Utils.CreateTableCell (html)); html = "<select id='lstDependencyConditions'>"; foreach (object value in Enum.GetValues (typeof (DBLaneDependencyCondition))) { if ((int) value == 0) continue; html += string.Format ("<option value='{0}'>{1}</option>", (int) value, value.ToString ()); } html += "</select>"; row.Cells.Add (Utils.CreateTableCell (html)); // host html = "<select id='lstDependentHosts'>"; html += "<option value='0'>Any</option>"; foreach (DBHost h in response.Hosts) { html += string.Format ("<option value='{0}'>{1}</option>", h.id, h.host); } html += "</select>"; row.Cells.Add (Utils.CreateTableCell (html)); row.Cells.Add (Utils.CreateTableCell (string.Empty)); row.Cells.Add (Utils.CreateTableCell (string.Empty)); row.Cells.Add (Utils.CreateTableCell (string.Format ("<a href='javascript:addDependency ({0})'>Add</a>", lane.id))); tblDependencies.Rows.Add (row); // deletion directives foreach (DBLaneDeletionDirectiveView directive in response.LaneDeletionDirectives) AddDeletionDirectiveRow (directive); if (response.FileDeletionDirectives != null && response.FileDeletionDirectives.Count > 0) { foreach (DBFileDeletionDirective directive in response.FileDeletionDirectives) { lstDeletionDirectives2.Items.Add (new ListItem (directive.name, directive.id.ToString ())); } } else { rowDeletionDirectives2.Visible = false; } foreach (DBDeleteCondition condition in Enum.GetValues (typeof (DBDeleteCondition))) lstDeletionDirectiveCondition1.Items.Add (new ListItem (condition.ToString (), ((int) condition).ToString ())); foreach (DBMatchMode mode in Enum.GetValues (typeof (DBMatchMode))) lstDeletionDirectiveGlobs1.Items.Add (new ListItem (mode.ToString (), ((int) mode).ToString ())); editorVariables.Lane = response.Lane; editorVariables.Master = Master; editorVariables.Variables = response.Variables; // notifications foreach (DBLaneNotification ln in response.LaneNotifications.FindAll ((v) => v.lane_id == response.Lane.id)) { DBNotification notification = response.Notifications.Find ((v) => v.id == ln.notification_id); tblNotifications.Rows.AddAt (tblNotifications.Rows.Count - 1, Utils.CreateTableRow (Utils.CreateTableCell (notification.name), Utils.CreateTableCell (Utils.CreateLinkButton ("remove_notification_" + ln.id.ToString (), "Remove", "RemoveNotification", ln.id.ToString (), OnLinkButtonCommand)))); } foreach (DBNotification notification in response.Notifications.FindAll ((v) => !response.LaneNotifications.Exists ((ln) => ln.notification_id == v.id && ln.lane_id == response.Lane.id))) { cmbNotifications.Items.Add (new ListItem (notification.name, notification.id.ToString ())); } } catch (Exception ex) { lblMessage.Text = ex.ToString ().Replace ("\n", "<br/>"); } }
public string GenerateHeader (GetViewTableDataResponse response, DBLane lane, DBHost host, bool horizontal) { string result; string format; string disabled_msg = string.Empty; if (!response.Enabled) disabled_msg = " (Disabled)"; if (Authentication.IsInRole (response, MonkeyWrench.DataClasses.Logic.Roles.Administrator)) { format = @"<h2>Build Matrix for <a href='EditLane.aspx?lane_id={0}'>'{2}'</a> on <a href='EditHost.aspx?host_id={5}'>'{4}'</a>{6}</h2><br/>"; } else { format = @"<h2>Build Matrix for '{2}' on '{4}'{6}</h2><br/>"; } format += @"<a href='ViewTable.aspx?lane_id={0}&host_id={1}&horizontal={3}'>Reverse x/y axis</a><br/>"; if (Authentication.IsInRole (response, MonkeyWrench.DataClasses.Logic.Roles.Administrator)) format += string.Format (@"<a href='javascript:clearRevisions ({0}, {1})'>Clear selected revisions</a><br/>", lane.id, host.id); format += "<br/>"; result = string.Format (format, lane.id, host.id, lane.lane, horizontal ? "false" : "true", host.host, host.id, disabled_msg); return result; }
private DBCommand FindCommand (DB db, DBLane lane, int? command_id, string command) { if ((command_id == null || command_id.Value <= 0) && string.IsNullOrEmpty (command)) return null; using (IDbCommand cmd = db.CreateCommand ()) { if (!command_id.HasValue) { cmd.CommandText = "SELECT * FROM Command WHERE command = @command"; DB.CreateParameter (cmd, "command", command); cmd.CommandText += " AND lane_id = @lane_id"; DB.CreateParameter (cmd, "lane_id", lane.id); } else { cmd.CommandText = "SELECT * FROM Command WHERE id = @id"; DB.CreateParameter (cmd, "id", command_id.Value); } using (IDataReader reader = cmd.ExecuteReader ()) { if (reader.Read ()) return new DBCommand (reader); } } return null; }
public int AddLane (WebServiceLogin login, string lane) { using (DB db = new DB ()) { VerifyUserInRole (db, login, Roles.Administrator); if (string.IsNullOrEmpty (lane)) throw new ArgumentOutOfRangeException ("name"); for (int i = 0; i < lane.Length; i++) { if (char.IsLetterOrDigit (lane [i])) { continue; } else if (lane [i] == '-' || lane [i] == '_' || lane [i] == '.') { continue; } else { throw new ArgumentOutOfRangeException (string.Format ("The character '{0}' isn't valid.", lane [i])); } } if (db.LookupLane (lane, false) != null) throw new ApplicationException (string.Format ("The lane '{0}' already exists.", lane)); DBLane dblane = new DBLane (); dblane.lane = lane; dblane.source_control = "svn"; dblane.Save (db); return dblane.id; } }
public void EditLane (WebServiceLogin login, DBLane lane) { using (DB db = new DB ()) { VerifyUserInRole (db, login, Roles.Administrator); var oldLane = FindLane (db, lane.id, null); lane.Save (db); Audit (login, "edited lane `{0}` -> `{1}`", Newtonsoft.Json.JsonConvert.SerializeObject(oldLane), Newtonsoft.Json.JsonConvert.SerializeObject(lane) ); } }
public LaneTreeNode (DBLane lane) : this (lane, null) { }
private static void UpdateBuildLogDB (DB db, DBLane lane, List<DBHost> hosts, List<DBHostLane> hostlanes) { List<DBRevision> revisions; List<DBCommand> commands = null; List<DBLaneDependency> dependencies = null; DBHostLane hostlane; DBWork work; bool got_dependencies = false; bool got_commands = false; try { Logger.Log ("Updating build db log... Got {0} hosts", hosts.Count); foreach (DBHost host in hosts) { hostlane = null; for (int i = 0; i < hostlanes.Count; i++) { if (hostlanes [i].lane_id == lane.id && hostlanes [i].host_id == host.id) { hostlane = hostlanes [i]; break; } } if (hostlane == null) { Logger.Log ("Lane '{0}' is not configured for host '{1}', not adding any work.", lane.lane, host.host); continue; } else if (!hostlane.enabled) { Logger.Log ("Lane '{0}' is disabled for host '{1}', not adding any work.", lane.lane, host.host); continue; } AddRevisionWork (db, lane, host); revisions = db.GetDBRevisionsWithoutWork (lane.id, host.id); Logger.Log ("Updating build db log... Got {0} revisions for host {1}", revisions.Count, host.host); foreach (DBRevision revision in revisions) { bool dependencies_satisfied = true; if (!got_commands) { commands = db.GetCommands (lane.id); got_commands = true; } if (!got_dependencies) { dependencies = DBLaneDependency_Extensions.GetDependencies (db, lane); got_dependencies = true; } if (dependencies != null) { Logger.Log ("Lane '{0}', revision '{1}' checking dependencies...", lane.lane, revision.revision); foreach (DBLaneDependency dependency in dependencies) dependencies_satisfied &= dependency.IsSuccess (db, revision.revision); Logger.Log ("Lane '{0}', revision '{1}' dependency checking resulted in: {2}.", lane.lane, revision.revision, dependencies_satisfied); } int revisionwork_id; bool pending_dependencies; using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = "SELECT add_revisionwork (@lane_id, @host_id, @revision_id);"; DB.CreateParameter (cmd, "lane_id", lane.id); DB.CreateParameter (cmd, "host_id", host.id); DB.CreateParameter (cmd, "revision_id", revision.id); revisionwork_id = (int) cmd.ExecuteScalar (); } using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = "SELECT state FROM RevisionWork WHERE id = @id;"; DB.CreateParameter (cmd, "id", revisionwork_id); pending_dependencies = (int) DBState.DependencyNotFulfilled == (int) cmd.ExecuteScalar (); } if (pending_dependencies && !dependencies_satisfied) continue; Logger.Log ("Pending dependencies: {0}", pending_dependencies); foreach (DBCommand command in commands) { work = null; if (pending_dependencies) { using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = "SELECT * FROM Work WHERE revisionwork_id = @revisionwork_id AND command_id = @command_id;"; DB.CreateParameter (cmd, "revisionwork_id", revisionwork_id); DB.CreateParameter (cmd, "command_id", command.id); using (IDataReader reader = cmd.ExecuteReader ()) { if (reader.Read ()) work = new DBWork (reader); } } } if (work == null) { work = new DBWork (); work.command_id = command.id; work.revisionwork_id = revisionwork_id; } work.State = dependencies_satisfied ? DBState.NotDone : DBState.DependencyNotFulfilled; work.Save (db); Logger.Log ("Saved revision {0}, host {2}, command {1}", revision.revision, command.command, host.host); } if (!dependencies_satisfied) { db.ExecuteScalar (string.Format ("UPDATE RevisionWork SET state = 9 WHERE id = {0} AND state = 0;", revisionwork_id)); } else { db.ExecuteScalar (string.Format ("UPDATE RevisionWork SET state = 0 WHERE id = {0} AND state = 9;", revisionwork_id)); } } } } catch (Exception ex) { Logger.Log ("There was an exception while updating build db: {0}", ex.ToString ()); } Logger.Log ("Updating build db log... [Done]"); }
public void EditLaneWithTags (WebServiceLogin login, DBLane lane, string[] tags) { using (DB db = new DB ()) using (var transaction = db.BeginTransaction()) { VerifyUserInRole (db, login, Roles.Administrator); var oldLane = FindLane (db, lane.id, null); lane.Save (db); using (var cmd = db.CreateCommand ()) { cmd.CommandText = "DELETE FROM LaneTag WHERE lane_id = @lane_id;"; DB.CreateParameter (cmd, "lane_id", lane.id); cmd.ExecuteNonQuery (); if (tags != null) { cmd.CommandText = "INSERT INTO LaneTag (lane_id, tag) VALUES (@lane_id, @tag);"; var tagParam = cmd.CreateParameter (); tagParam.ParameterName = "tag"; cmd.Parameters.Add (tagParam); foreach (var tag in tags) { tagParam.Value = tag; cmd.ExecuteNonQuery (); } } } transaction.Commit (); Audit (login, "edited lane `{0}` -> `{1}`", Newtonsoft.Json.JsonConvert.SerializeObject(oldLane), Newtonsoft.Json.JsonConvert.SerializeObject(lane) ); } }
static void CollectWork (List<DBCommand> commands_in_lane, List<DBLane> lanes, DBLane lane, List<DBCommand> commands) { while (lane != null) { commands_in_lane.AddRange (commands.Where (w => w.lane_id == lane.id)); lane = lanes.FirstOrDefault ((v) => lane.parent_lane_id == v.id); } }
private DBRevision FindRevision (DB db, DBLane lane, string revision) { using (var cmd = db.CreateCommand ()) { cmd.CommandText = "SELECT * FROM Revision WHERE lane_id = @laneid AND revision = @rev;"; DB.CreateParameter (cmd, "laneid", lane.id); DB.CreateParameter (cmd, "rev", revision); using (var reader = cmd.ExecuteReader ()) { if (reader.Read ()) return new DBRevision (reader); } } return null; }
public static void FindPeopleForCommit (DBLane lane, DBRevision revision, List<DBPerson> people) { if (lane.source_control == "git") { GITUpdater.FindPeopleForCommit (lane, revision, people); /* } else if (lane.source_control == "svn") { SVNUpdater.FindPeopleForCommit (lane, revision, people); * */ } else { log.ErrorFormat ("Unknown source control for lane {0}: {1}", lane.lane, lane.source_control); } }
public string GeneratePager (GetViewTableDataResponse response, DBLane lane, DBHost host, int page, int limit) { StringBuilder pager = new StringBuilder (); int total = response.Count; int pages = total / limit; if (total % limit != 0) pages++; Console.WriteLine ("Pages: {0} total: {1}", pages, total); if (page > pages - 1) page = pages - 1; int range = 5; pager.AppendFormat ("<p> Page "); if (pages < (range * 2)) { for (int i = 0; i < pages; i++) { pager.Append (GeneratePageLink (host.id, lane.id, i + 1, limit)); } } else { if (page <= (range + 1)) { for (int i = 0; i < (page + range); i++) { if (page == i) pager.Append (string.Format ("<b>{0}</b>", i + 1)); else pager.Append (GeneratePageLink (host.id, lane.id, i + 1, limit)); } pager.AppendFormat ("..."); pager.Append (GeneratePageLink (host.id, lane.id, pages - 2, limit)); pager.Append (GeneratePageLink (host.id, lane.id, pages - 1, limit)); } else if (page > (pages - range - 4)) { pager.Append (GeneratePageLink (host.id, lane.id, 1, limit)); pager.Append (GeneratePageLink (host.id, lane.id, 2, limit)); pager.AppendFormat ("..."); for (int i = page - range; i < pages; i++) { if (page == i) pager.Append (string.Format ("<b>{0}</b>", i + 1)); else pager.Append (GeneratePageLink (host.id, lane.id, i + 1, limit)); } } else { pager.Append (GeneratePageLink (host.id, lane.id, 1, limit)); pager.Append (GeneratePageLink (host.id, lane.id, 2, limit)); pager.AppendFormat ("..."); for (int i = page - range; i < page + range; i++) { if (page == i) pager.Append (string.Format ("<b>{0}</b>", i + 1)); else pager.Append (GeneratePageLink (host.id, lane.id, i + 1, limit)); } pager.AppendFormat ("..."); pager.Append (GeneratePageLink (host.id, lane.id, pages - 2, limit)); pager.Append (GeneratePageLink (host.id, lane.id, pages - 1, limit)); } } pager.AppendFormat ("</p>"); return pager.ToString (); }
public void EditLane (WebServiceLogin login, DBLane lane) { //WebServiceResponse response = new WebServiceResponse (); using (DB db = new DB ()) { VerifyUserInRole (db, login, Roles.Administrator); lane.Save (db); } }
public string GenerateLaneTable (GetViewTableDataResponse response, DBLane lane, DBHost host, bool horizontal, int page, int limit) { StringBuilder matrix = new StringBuilder (); StringBuilder tooltip = new StringBuilder (); bool new_revision = true; int revision_id = 0; List<DBRevisionWorkView> views = response.RevisionWorkViews; List<List<TableNode>> table = new List<List<TableNode>> (); List<TableNode> row = new List<TableNode> (); List<TableNode> header = new List<TableNode> (); for (int i = 0; i < views.Count; i++) { while (header.Count <= views [i].sequence) { header.Add (null); } if (header [views [i].sequence] != null) continue; var node = new TableNode (string.Format ("<a href='ViewWorkTable.aspx?lane_id={0}&host_id={1}&command_id={2}'>{3}</a>", lane.id, host.id, views [i].command_id, views [i].command)); node.command_id = views [i].command_id; header [views [i].sequence] = node; } header.RemoveAll (delegate (TableNode match) { return match == null; }); header.Insert (0, new TableNode ("Revision", true)); header.Insert (1, new TableNode ("Diff", true)); header.Insert (2, new TableNode ("Author", true)); //if (Authentication.IsInRole (response, MonkeyWrench.DataClasses.Logic.Roles.Administrator)) { // header.Insert (3, new TableNode ("Select", true)); //} header.Add (new TableNode ("Host", true)); header.Add (new TableNode ("Duration", true)); table.Add (header); bool failed = false; double duration = 0; for (int i = 0; i < views.Count; i++) { DBRevisionWorkView view = views [i]; DBState revisionwork_state = (DBState) view.revisionwork_state; DBState state = (DBState) view.state; new_revision = revision_id != view.revision_id; revision_id = view.revision_id; if (new_revision) { if (i > 0) { table.Add (row); row [row.Count - 1] = new TableNode (TimeSpan.FromSeconds (duration).ToString (), row [0].@class); } string revision = view.revision; long dummy; if (revision.Length > 16 && !long.TryParse (revision, out dummy)) revision = revision.Substring (0, 8); string clazz = revisionwork_state.ToString ().ToLower (); clazz = clazz + " " + DarkenColor (clazz, table.Count); row = new List<TableNode> (); tooltip.Length = 0; tooltip.AppendFormat ("Author: {0}.", view.author); if (view.starttime.Date.Year > 2000) tooltip.AppendFormat (" Build start date: {0}.", view.starttime.ToUniversalTime ().ToString ("yyyy/MM/dd HH:mm:ss UTC")); row.Add (new TableNode (string.Format ("<a href='ViewLane.aspx?lane_id={0}&host_id={1}&revision_id={2}' title='{4}'>{3}</a>", lane.id, host.id, view.revision_id, revision, tooltip.ToString ()), clazz)); row.Add (new TableNode (string.Format ("<a href='GetRevisionLog.aspx?id={0}'>diff</a>", view.revision_id))); row.Add (new TableNode (view.author)); //if (Authentication.IsInRole (response, MonkeyWrench.DataClasses.Logic.Roles.Administrator)) // row.Add (new TableNode (string.Format ("<input type=checkbox id='id_revision_chk_{1}' name='revision_id_{0}' />", view.revision_id, i))); while (row.Count < header.Count - 2) row.Add (new TableNode ("-")); row.Add (new TableNode (view.workhost ?? "")); row.Add (new TableNode ("")); failed = false; duration = 0; } if (view.endtime > view.starttime) duration += (view.endtime - view.starttime).TotalSeconds; if (state == DBState.Failed && !view.nonfatal) failed = true; else if (revisionwork_state == DBState.Failed) failed = true; // result string result; bool completed = true; switch (state) { case DBState.NotDone: completed = false; result = failed ? "skipped" : "queued"; break; case DBState.Executing: completed = false; result = "running"; break; case DBState.Failed: result = view.nonfatal ? "issues" : "failure"; break; case DBState.Success: result = "success"; break; case DBState.Aborted: result = "aborted"; break; case DBState.Timeout: result = "timeout"; break; case DBState.Paused: completed = false; result = "paused"; break; case DBState.Ignore: completed = false; result = "ignore"; break; default: completed = true; result = "unknown"; break; } for (int j = 2; j < header.Count; j++) { if (header [j].command_id == view.command_id) { if (completed) { row [j] = new TableNode (string.Format ("<a href='{0}'>{1}</a>", Utilities.CreateWebServiceDownloadUrl (Request, view.id, view.command + ".log", true), result)); } else { row [j] = new TableNode (result); } row [j].@class = result + " " + DarkenColor (result, table.Count); break; } } } table.Add (row); row [row.Count - 1] = new TableNode (TimeSpan.FromSeconds (duration).ToString (), row [0].@class); matrix.AppendLine ("<table class='buildstatus'>"); if (horizontal) { for (int i = 0; i < header.Count; i++) { matrix.Append ("<tr>"); for (int j = 0; j < table.Count; j++) { TableNode node = table [j] [i]; string td = node.is_header ? "th" : "td"; matrix.Append ('<'); matrix.Append (td); if (node.@class != null) { matrix.Append (" class='"); matrix.Append (node.@class); matrix.Append ("'"); } /* if (node.style != null) { matrix.Append (" style='"); matrix.Append (node.style); matrix.Append ("'"); }*/ matrix.Append (">"); matrix.Append (node.text); matrix.Append ("</"); matrix.Append (td); matrix.Append (">"); } matrix.AppendLine ("</tr>"); } } else { for (int i = 0; i < table.Count; i++) { matrix.Append ("<tr>"); for (int j = 0; j < row.Count; j++) { TableNode node = table [i] [j]; string td = node.is_header ? "th" : "td"; matrix.Append ('<'); matrix.Append (td); if (node.@class != null) { matrix.Append (" class='"); matrix.Append (node.@class); matrix.Append ("'"); } /* if (node.style != null) { matrix.Append (" style='"); matrix.Append (node.style); matrix.Append ("'"); }*/ matrix.Append (">"); matrix.Append (node.text); matrix.Append ("</"); matrix.Append (td); matrix.Append (">"); } matrix.AppendLine ("</tr>"); } } matrix.AppendLine ("</table>"); return matrix.ToString (); }
public void EditLaneWithTags (WebServiceLogin login, DBLane lane, string[] tags) { Logger.Log ("EditLaneWithTags ({0}, {1})", lane.id, tags == null ? "null" : tags.Length.ToString ()); using (DB db = new DB ()) { VerifyUserInRole (db, login, Roles.Administrator); lane.Save (db); using (var cmd = db.CreateCommand ()) { var cmdText = new StringBuilder (); cmdText.AppendFormat ("DELETE FROM LaneTag WHERE lane_id = {0};", lane.id).AppendLine (); if (tags != null) { for (int i = 0; i < tags.Length; i++) { cmdText.AppendFormat ("INSERT INTO LaneTag (lane_id, tag) VALUES ({0}, @tag{1});", lane.id, i).AppendLine (); DB.CreateParameter (cmd, "tag" + i.ToString (), tags [i]); } } cmd.CommandText = cmdText.ToString (); cmd.ExecuteNonQuery (); } } }
protected void cmdSave_Click (object sender, EventArgs e) { string str_lane = txtID.Text; int lane_id; int? parent_lane_id = null; DBLane lane; if (!int.TryParse (str_lane, out lane_id)) return; Logger.Log ("lstParentLane: {0}", lstParentLane.SelectedValue); if (!string.IsNullOrEmpty (lstParentLane.SelectedValue)) parent_lane_id = int.Parse (lstParentLane.SelectedValue); lane = new DBLane (); lane.id = lane_id; lane.lane = txtLane.Text; lane.max_revision = txtMaxRevision.Text; lane.min_revision = txtMinRevision.Text; lane.repository = txtRepository.Text; lane.commit_filter = txtCommitFilter.Text; lane.source_control = cmbSourceControl.Text; lane.parent_lane_id = (parent_lane_id.HasValue && parent_lane_id.Value != 0) ? parent_lane_id : null; Master.WebService.EditLane (Master.WebServiceLogin, lane); RedirectToSelf (); }
protected override bool UpdateRevisionsInDBInternal (DB db, DBLane lane, string repository, Dictionary<string, DBRevision> revisions, List<DBHost> hosts, List<DBHostLane> hostlanes, string min_revision, string max_revision) { string revision; bool update_steps = false; List<DateTime> used_dates; DBRevision r; List<GitEntry> log; if (string.IsNullOrEmpty (max_revision)) max_revision = "remotes/origin/master"; GITUpdater.log.InfoFormat ("Updating lane: '{0}', repository: '{1}' min revision: '{2}' max revision: '{3}'", lane.lane, repository, min_revision, max_revision); log = GetGITLog (lane, repository, min_revision, max_revision); if (log == null || log.Count == 0) { GITUpdater.log.WarnFormat ("Didn't get a git log for '{0}'", repository); return false; } GITUpdater.log.InfoFormat ("Got {0} log records", log.Count); used_dates = new List<DateTime> (); foreach (GitEntry entry in log) { string hash = entry.revision; string unix_timestamp_str = entry.timestamp; long unix_timestamp; string author = entry.author; DateTime date; if (!long.TryParse (unix_timestamp_str, out unix_timestamp)) { /* here something is wrong, this way the commit shows up as the first one so that it's easy to spot and start investigating */ date = DateTime.Now.AddYears (20); GITUpdater.log.WarnFormat ("Could not parse timestamp '{0}' for revision '{1}' in lane '{2}' in repository {3}", unix_timestamp_str, entry.revision, lane.lane, repository); } else { const long EPOCH_DIFF = 0x019DB1DED53E8000; /* 116444736000000000 nsecs */ const long RATE_DIFF = 10000000; /* 100 nsecs */ date = DateTime.FromFileTimeUtc ((unix_timestamp * RATE_DIFF) + EPOCH_DIFF); } /* * The timestamp resolution on my machine seems to be 1 second, * which means that if you commit fast enough you'll get * commits with the same date. This is a very bad thing since * the commits are order by the commit date, and if two commits * have the same date the order they're build / shown is random * (the db decides whatever it feels like). Work around this by * keeping a list of used dates and if the date has already * used, add a millisecond to it (and try again). Note that * there is still a possibility of duplicate dates: if there * already is a revision in the database with this date (from * a previous run of the scheduler). * * It may seem like there is a very small possibility of having * two commits within a second, but this happens all the time * for our test suite. */ while (used_dates.Contains (date)) { date = date.AddMilliseconds (1); } used_dates.Add (date); revision = hash; if (revision == null) continue; if (revisions.ContainsKey (revision)) { /* Check if we've saved the wrong date earlier and fix it */ if (revisions [revision].date > new DateTime (2030, 1, 1)) { /* Hopefully this code will not stay here for 20 years */ revisions [revision].date = date; revisions [revision].Save (db); GITUpdater.log.WarnFormat ("Detected wrong date in revision '{0}' in lane '{1}' in repository {2}, fixing it", revision, lane.lane, repository); } // Log (2, "Already got {0}", revision); continue; } if (!string.IsNullOrEmpty (lane.commit_filter)) { FetchFiles (entry, repository); if (DoesFilterExclude (entry, lane.commit_filter)) continue; } r = new DBRevision (); r.revision = revision; r.lane_id = lane.id; r.author = author; if (string.IsNullOrEmpty (r.author)) { GITUpdater.log.WarnFormat ("No author specified in r{0} in {1}", r.revision, repository); r.author = "?"; } r.date = date; r.log_file_id = null; r.Save (db); update_steps = true; GITUpdater.log.DebugFormat ("Saved revision '{0}' for lane '{1}' author: {2}, date: {3:yyyy/MM/dd HH:mm:ss.ffffff} {4} {5}", r.revision, lane.lane, r.author, r.date, unix_timestamp, unix_timestamp_str); } return update_steps; }