상속: DBRecord
예제 #1
0
	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;
		}
	}
예제 #2
0
	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;
	}
예제 #3
0
	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);
	}
예제 #4
0
	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;
			}
		}
예제 #6
0
	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);
			}
		}
	}
예제 #7
0
	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}&amp;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}&amp;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;
		}
예제 #10
0
		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;
		}
예제 #11
0
	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}&amp;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}&amp;host_id={1}'>table</a>)</h2><br/>", lane.id, host.id, lane.lane, host.host, description, revision.revision, revision.id);
		}
	}
예제 #12
0
		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 ());
			}
		}
예제 #13
0
		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;
			}
		}
예제 #14
0
	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}&amp;file_id={0}'>{2}</a>", file.id, lane.id, file.name),
					file.mime,
					string.Format ("<a href='EditLane.aspx?lane_id={1}&amp;action=deleteFile&amp;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}&amp;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}&amp;command_id={3}&amp;action=switchAlwaysExecute'>{2}</a>", lane.id, (!command.alwaysexecute).ToString (), command.alwaysexecute ? "yes" : "no", command.id),
					string.Format ("<a href='EditLane.aspx?lane_id={0}&amp;command_id={3}&amp;action=switchNonFatal'>{2}</a>", lane.id, (!command.nonfatal).ToString (), command.nonfatal ? "yes" : "no", command.id),
					string.Format ("<a href='EditLane.aspx?lane_id={0}&amp;command_id={1}&amp;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}&amp;action=deletecommand&amp;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}&amp;host_id={1}&amp;action=removeHost'>Remove</a> ", lane.id, view.host_id);
				html = html + string.Format ("<a href='EditLane.aspx?lane_id={0}&amp;host_id={1}&amp;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/>");
		}
	}
예제 #15
0
	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}&amp;host_id={1}&amp;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;
	}
예제 #16
0
		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;
		}
예제 #17
0
		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;
			}
		}
예제 #18
0
		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)
				);
			}
		}
예제 #19
0
	public LaneTreeNode (DBLane lane)
		: this (lane, null)
	{
	}
예제 #20
0
		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]");
		}
예제 #21
0
		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)
				);
			}
		}
예제 #22
0
		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);
			}
		}
예제 #23
0
		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;
		}
예제 #24
0
		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);
			}
		}
예제 #25
0
	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&nbsp;");
		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 ();
	}
예제 #26
0
		public void EditLane (WebServiceLogin login, DBLane lane)
		{
			//WebServiceResponse response = new WebServiceResponse ();
			using (DB db = new DB ()) {
				VerifyUserInRole (db, login, Roles.Administrator);
				lane.Save (db);
			}
		}
예제 #27
0
	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}&amp;host_id={1}&amp;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}&amp;host_id={1}&amp;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 ();
	}
예제 #28
0
		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 ();
				}
			}
		}
예제 #29
0
	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 ();
	}
예제 #30
0
		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;
		}