TeamCity reporting that it’s out of diskspace

I installed TeamCity on a server (just the professional edition).

The server was installed under D:\TeamCity, with it’s (only) agent under D:\TeamCity\buildAgent.

I then started creating a project. At one point I modified the VSC Checkout rules, and then stuff went downhill.

First of all, a VSC root is not under some sort of revision control like build configurations, which is a pain in the *** to track your changes. Even the Checkout rules aren’t (which are build configuration specific).

Anyway, this was the error:

Free disk space requirement
[18:18:07][Free disk space requirement] Removing files to meet 3.0Gb of free disk space required for directory D:\TeamCity\buildAgent\work\cc94054af2903311 (only 0.0b is free now).
[18:18:07][Free disk space requirement] Removing files to meet 3.0Gb of free disk space required for directory D:\TeamCity\buildAgent\temp (only 12.7Gb is free now).
[18:18:07][Free disk space requirement] Free disk space requirement of 3.0Gb could not be met for directory D:\TeamCity\buildAgent\work\cc94054af2903311 (only 0.0b is free)
[18:18:07][Free disk space requirement] Free disk space requirement of 3.0Gb could not be met for directory D:\TeamCity\buildAgent\temp (only 12.7Gb is free)

Weird errors, because the disk actually had >3.0GB free (not 3.0Gb, that’s a typo on their side).

I checked all the disks, maybe it tried to write to the C: for temp files, but that one had enough space too.

Upon further investigation I saw I made a typo in the Checkout rules of a particular VCS root which caused the fail:

I set the rule like this:

+:Foo=Bar

As you can see, it misses the >

So the correct one should be

+:Foo=>Bar

It’s very annoying they don’t have error checking for that.

Have a good one,

-Kristof

ASP.NET MVC Mobile: where is my style?

I was playing with ASP.NET MVC Mobile to start something quickly for my phone.

I then updated the NuGet packages, and my style was GONE.

Seems that jQuery 1.9.* is incompatible with jQuery.Mobile 1.2.

According to the website 1.3 is out, so the package should soon be there, so until then you can revert from jQuery 1.9.* to 1.8.3 with the following code in your Package Manager Console:

uninstall-package jQuery -Force # ignore that some have dependencies on jQuery
install-package jQuery -Version 1.8.3

jQuery downgrade

Have a good one,

-Kristof

WebClient not sending credentials? Here’s why!

TL;DR version here.
This post applies to more than just GitHub, read the rest to see the behavior!

I was playing with the GitHub API (more specifically generating a new OAuth token).

So what you need to do, as per the documentation, is to post a certain JSON string to https://api.github.com/authorizations, with Basic Authentication. I’m going to use the WebClient class for this.

This is the JSON string that you need to post:

{
  "scopes": [
    "repo"
  ],
  "note": "API test"
}

Now this is the code I used:

var content = new 
			{
				scopes = new[] { "repo" },
				note = "API test",
			};

var webClient = new WebClient
	                {
				Credentials = new NetworkCredential("*****", "*****"),
	                };

// JsonConvert is from NewtonSoft.Json, very handy!
string serializedObject = JsonConvert.SerializeObject(content);

string reply = webClient.UploadString(new Uri("https://api.github.com/authorizations"), "POST", serializedObject);

dynamic deserializedReply = JsonConvert.DeserializeObject(reply);

Console.WriteLine(deserializedReply.token);
Console.ReadLine();

However, when using this piece of code I always get a 404 not found.

Reading through the Github API documentation yields the following:

There are three ways to authenticate through GitHub API v3. Requests that require authentication will return 404, instead of 403, in some places. This is to prevent the accidental leakage of private repositories to unauthorized users.

(emphasis mine)

So there’s a good change that we just hit Github’s security through obscurity, so we do normally get a 403.

In fact, I tested it with Github Enterprise, and that one just returns a 403, so that’s how I figured out that the URL I was calling is correct (Github Enterprise doesn’t hide information like the regular does):

403 forbidden from a Github Enterprise instance

Let’s try the same code on a Simple IIS website with basic authentication:

Screenshot (12)

I then simplified the code to just download the contents of the website, with a simple GET:

var webClient = new WebClient
	                {
		                Credentials = new NetworkCredential("*****", "*****"),
	                };

string reply = webClient.DownloadString(new Uri("http://localhost/CredentialTest"));

Console.WriteLine(reply);
Console.ReadLine();

So that gives me the response (Default.aspx contains ‘Hi, it works’).

Now what’s going on? Is it the POST that conflicts?

Using the same code, but instead of DownloadString, I upload some arbitrary piece of text with UploadString which by default uses POST.

var webClient = new WebClient
	                {
		                Credentials = new NetworkCredential("*****", "*****"),
	                };

string reply = webClient.UploadString(new Uri("http://localhost/CredentialTest/Default.aspx"), "somerandomstuff");

Console.WriteLine(reply);
Console.ReadLine();

Please note that I post directly to Default.aspx. IIS doesn’t allow postings to directories (I’m sure you can enable it).

Anyway, this also works.

Next step? I was thinking that WebClient maybe only sends the credentials over when it detects that the machines are in the same domain / workstation?

Let’s find out with Fiddler.

I first monitored the flow for the console app to IIS and I was surprised to see that there were actually two requests, and what’s even more weird is that the first request doesn’t send the credentials (notice I still use POST, to mimic our code to connect to GitHub):

First request to IIS

Instead of returning a 403 on the file, IIS nicely returns a 401 with the WWW-Authenticate header:

first response

The WebClient is then smart enough to resend the request WITH the credentials:

second request

And then the server nicely responds with a 200, and the contents are sent (notice the picture are JUST the headers).

second response

This flow is always the same, whether it is GET or POST (what’s weird is that when you want to post a 2GB file, you send it, server replies 401, and you need to send the 2GB file again…).

Now that we know that our WebClient is behaving correctly, I decided to go and look at the request and response from GitHub:

The first request (like with IIS), doesn’t contain the Authorization header:

First GitHub request

However, in contrast to IIS, GitHub doesn’t play nice. It doesn’t send a 401 with a WWW-Authenticate header, it just returns 404 (or 403 on Github Enterprise).

First and only response from GitHub

For GitHub it is perfectly valid to send a 404 if it doesn’t want to disclose information.

The only problem is just that the WebClient doesn’t know what to do and thus, we need to do stuff ourselves!

We need to manually inject the headers when calling Github (or any webserver) at the first request:

var content = new 
			{
				scopes = new[] { "repo" },
				note = "API test",
			};

var webClient = new WebClient();

// replace webClient.Credentials = new NetWorkCredentials("*****","******") by these 2 lines

// create credentials, base64 encode of username:password
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes("*****" + ":" + "*****"));

// Inject this string as the Authorization header
webClient.Headers[HttpRequestHeader.Authorization] = string.Format("Basic {0}", credentials);

// Continue as you are used to!
string serializedObject = JsonConvert.SerializeObject(content);

string reply = webClient.UploadString(new Uri("https://api.github.com/authorizations"), "POST", serializedObject);

dynamic deserializedReply = JsonConvert.DeserializeObject(reply);

Console.WriteLine(deserializedReply.token);
Console.ReadLine();

And we have our token!

Borat Great SuccessHave a good one!

-Kristof