public ReportBuildBotStatusResponse ReportBuildBotStatus (WebServiceLogin login, BuildBotStatus status) { ReportBuildBotStatusResponse response = new ReportBuildBotStatusResponse (); using (DB db = new DB ()) { VerifyUserInRole (db, login, Roles.BuildBot, true); log.DebugFormat ("BuildBot '{2}' reported in. v{0}: {1}", status.AssemblyVersion, status.AssemblyDescription, status.Host); using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = @" DELETE FROM BuildBotStatus WHERE host_id = (SELECT id FROM Host WHERE host = @host); INSERT INTO BuildBotStatus (host_id, version, description) VALUES ((SELECT id FROM Host WHERE host = @host), @version, @description); "; DB.CreateParameter (cmd, "host", status.Host); DB.CreateParameter (cmd, "version", status.AssemblyVersion); DB.CreateParameter (cmd, "description", status.AssemblyDescription); cmd.ExecuteNonQuery (); } using (IDbCommand cmd = db.CreateCommand ()) { cmd.CommandText = "SELECT * FROM Release INNER JOIN Host ON Host.release_id = Release.id WHERE Host.host = @host;"; DB.CreateParameter (cmd, "host", status.Host); using (IDataReader reader = cmd.ExecuteReader ()) { if (reader.Read ()) { DBRelease release = new DBRelease (reader); response.ConfiguredVersion = release.version; response.ConfiguredRevision = release.revision; } } } } return response; }
private static bool Update (BuildBotStatus status, ReportBuildBotStatusResponse status_response) { StringBuilder output = new StringBuilder (); Logger.Log ("This host is at version {0}, while it should be running version {1} ({2}). Will try to update.", status.AssemblyVersion, status_response.ConfiguredVersion, status_response.ConfiguredRevision); try { /* Check with git status if working copy is clean */ using (Process git = new Process ()) { git.StartInfo.FileName = "git"; git.StartInfo.Arguments = "status -s"; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardOutput = true; git.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine (e.Data); } }; git.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine (e.Data); } }; git.Start (); git.BeginErrorReadLine (); git.BeginOutputReadLine (); if (!git.WaitForExit ((int) TimeSpan.FromMinutes (1).TotalMilliseconds)) { Logger.Log ("Builder.Update (): Could not get git status, git didn't get any status in 1 minute."); return false; } if (git.ExitCode != 0) { Logger.Log ("Builder.Update (): git status failed: {0}", output.ToString ()); return false; } string stdout = output.ToString ().Trim (); if (string.IsNullOrEmpty (stdout)) { /* OK */ } else if (stdout.Contains ("nothing to commit (working directory clean)")) { /* OK - git 1.6 doesn't seem to understand the -s flag */ } else { Logger.Log ("Builder.Update (): git status shows that there are local changes: \n{0}", output); return false; } } /* git status shows we're clean, now run git fetch */ output.Length = 0; using (Process git = new Process ()) { git.StartInfo.FileName = "git"; git.StartInfo.Arguments = "fetch"; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardOutput = true; git.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine (e.Data); } }; git.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine (e.Data); } }; git.Start (); git.BeginErrorReadLine (); git.BeginOutputReadLine (); if (!git.WaitForExit ((int) TimeSpan.FromMinutes (1).TotalMilliseconds)) { Logger.Log ("Builder.Update (): git fetch didn't finish in 1 minute"); return false; } if (git.ExitCode != 0) { Logger.Log ("Builder.Update (): git status failed: {0}", output.ToString ()); return false; } } /* git fetch done, checkout the revision we want */ output.Length = 0; using (Process git = new Process ()) { git.StartInfo.FileName = "git"; git.StartInfo.Arguments = "reset --hard " + status_response.ConfiguredRevision; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardOutput = true; git.OutputDataReceived += delegate (object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine (e.Data); } }; git.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine (e.Data); } }; git.Start (); git.BeginErrorReadLine (); git.BeginOutputReadLine (); if (!git.WaitForExit ((int) TimeSpan.FromMinutes (1).TotalMilliseconds)) { Logger.Log ("Builder.Update (): Could not checkout the required revision in 1 minute."); return false; } if (git.ExitCode != 0) { Logger.Log ("Builder.Update (): git reset failed: {0}", output.ToString ()); return false; } } Logger.Log ("Successfully updated to {0} {1})", status_response.ConfiguredVersion, status_response.ConfiguredRevision); } catch (Exception ex) { Logger.Log ("Builder.Update (): exception caught: {0}", ex.Message); return false; } return true; }