mike-obrien.net Resume Blog Labs
Monday, December 04, 2006

The following steps outline how to install and configure Subversion v1.4.

1. Download the latest subversion package from here (Described as "Windows installer with the basic win32 binaries").

2. Using svnadmin (In the Subversion bin folder) create a new repository: svnadmin create drive:\my\repository\path

3. Setup the Subversion server as a windows service as specified here. If you want to store repositories on drives other than the drive the subversion service is running on or you would like access to be restricted to a certain path you will need to specify a repository root. This can be specified in the service setup.

4. Configure security as specified here.

5. Install a Subversion client such as TortuousSVN and test access to the repository: svn://MyServer/MyRepo

Monday, December 04, 2006 10:51:42 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 

I want to start off by saying that I am running subserve v1.4 as a Windows service. From what I have read configuration may be somewhat different when using httpd, SSH or on another OS. So the following may or may not fully apply to other access methods, versions or OS’s.

svnserve.conf

The first repository security configuration file you will encounter is the svnserve.conf file. It appears that Subversion looks for this file specifically under the “conf” folder within the repository tree. I don’t believe there is a way to configure this path or the filename it looks for. This file has only one section called “general”. It contains 5 basic security settings. The settings are as follows:

anon-access: Valid values for this setting are read, write or none. This value specifies repository wide access for anonymous users. If there is a conflict with this setting and with folder permissions specified in the authz file, the most restrictive permission is applied.

auth-access: Valid values for this setting are read, write or none. This value specifies repository wide access for authenticated users. If there is a conflict with this setting and with folder permissions specified in the authz file, the most restrictive permission is applied.

password-db: This specifies a path to a user database. This can be an absolute path (“C:\config\passwd”) or a relative path (“..\..\config\passwd”). If no path is specified only anonymous access will be supported. Only the anon-access permission will be in force.

authz-db: This specifies a path to a folder permissions database. This can be an absolute path (“C:\config\authz”) or a relative path (“..\..\config\authz”). If no path is specified then path based permissions are not applied. Only the anon-access and auth-access permissions will be in force.

realm: This is a string that serves as a unique identifier which identifies a realm or security domain the repository is associated with. A realm is basically the user base contained in the user database (passwd file). Each repository that shares a single user database should have the same realm specified. So for example if you had a user database at “C:\config\passwd” which was used by three repositories, all three repositories should have the same realm specified.

passwd

The second file you will encounter is the user database. The name of this file is passwd by default but can be anything. If user authentication is desired the path to this file must be set in the password-db setting in the svnserve.conf file. If no path is set for this setting, no user authentication will take place. The user database can be shared by multiple repositories. Each repository that shares a single user database should have the same realm specified. The user database contains only one section called “users”. The settings in this group are username/password pairs. For example:

[users]
bsimpson =
R@dio@ctiveM@n
lsimpson = Bl33dingGumsMurphy
mburns=Smith3rs
djquimby=V0t3Quimby

authz

The third file you will encounter is the path based permissions database. The name of this file is authz by default but can be anything. If path based permissions are desired the path to this file must be set in the authz-db setting in the svnserve.conf file. This file defines user groups and path permissions. The first section in this file is called “groups”. Here you can specify groups and their membership. Each setting is a group name and a comma separated user list. It does not appear that white space in this list causes any problems. Unfortunately as of  Subversion 1.4 you cannot specify user groups in the user database (passwd), only in this file. Here is an example of the “groups” section:

[groups]
admin = mburns, djquimby
users =  bsimpson, lsimpson

The sections that follow are path specific permissions. The section name is the path. The path begins with a forward slash but must not end with one. Evidently (As of Subversion 1.4) the “repository” prefix for repository specific permissions (IE: [repository:/yada/yada]) is ignored when using svnserve to access repositories. It appears that it is only recognized when using the httpd access method. So separate files would have to be maintained to provide repository specific folder permissions. Otherwise if identical paths existed in two or more repositories the permissions for those paths would be identical, there would be no way to differentiate them. Each path permission section contains members which could be a group name prefixed with an ampersand (@), wildcard (*) denoting all users (Including anonymous) or simply a username. The permissions are ‘r’ for readonly, ‘rw’ for read/write or ‘’ (Blank) for no access (Including anonymous users). Permissions are inherited from the parent folder if no permissions are specified for a particular path. If permissions conflict, the least restrictive permissions are applied. Here is an example of path permissions:

[/common]
* = rw

[/config/admin]
@admin=rw
lsimpson=r

[/docs]
@users=rw
@admin=rw

[/secure]
@admin=r
@users=

Monday, December 04, 2006 10:08:48 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 

I am running svnserve as a windows service on our build server. I thought it was pretty cool that you could point repositories to central security configuration files. This is really nice if you have multiple repositories, only two files to maintain for each relm. Problem is though that when you set a repository specific folder permission ([repository:/yada]) in the authz file it is totally ignored. For example:

[repository:/reporoot/repo1]
@group1=rw

[repository:/reporoot/repo2]
@group2=rw

This does nothing! I did a little searching on "the google" and evidently the repository specific prefix only works with httpd access. For svnserve access you have to specify an authz file for each repository to specify repository specific permissions. Posts here and here discuss this issue.

Monday, December 04, 2006 7:51:12 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 

Many times when we think of OSS we think "cost savings" or “free”... Not so. There are many hidden costs that accompany the integration of OSS into your infrastructure. I’m currently in the process of integrating some OSS into our infrastructure and am really seeing this. Now don’t get me wrong I’m a big fan (and user) of OSS but it’s important to see the big picture when making decisions and planning projects that involve OSS.

One of the hidden costs is learning and configuring. OSS, from what I have seen, seems to be seriously lacking when it comes to ease of use and configurability. Many times OSS is command line based, configuration is in INI style config files. It takes time to read through documentation (Which may be sparse in some cases). I have also found that actually playing around with the app and configuration is in some cases the best way to figure out how to configure and use the software. Again, all of this takes time. On the other hand the pretty app that you pay for will (If it’s any good) have an intelligent installer, very intuitive GUI, and lots of support and documentation. I recently had an experience where I setup one of those “pretty, paid for” apps and I literally had it up and running and configured in a couple of hours. I was totally blown away! If it were OSS it would more than likely taken me a couple of days (Or more) to get in there and figure it out.

Another hidden cost I have seen is maintenance… Many OSS software packages have cryptic or crud management and/or maintenance interfaces. These can be cumbersome and time consuming to work with and can be difficult to get others up to speed on using them. This may also lead to neglect because it’s a pain to work with or others don’t feel they have the time to learn it. The app that you pay for (If it’s any good) will probably have a slick interface to maintain and administer.

Again, I’m not knocking OSS, I think OS development is a wonderful thing. There are a lot of awesome OS projects out there. I also think that OSS fills an important roll in any infrastructure. But when you decide to go the OSS route you can’t be in the mindset that because it’s OS it’s free. You really have to think about the pros and cons and make a decision based on that. In some cases it may actually be cheaper (And more advantageous) to buy instead of going the OSS route.

As a side note, I have heard some balk at “pretty, paid for” apps for various reasons, some valid some not objective at all. But the reality is this: Those days as a single guy staying up all night eating Doritos, drinking Mt Dew and hacking on all kinds of interesting stuff are over. In the real world you have a family, deadlines and clients (both internal and external). Time is really of the essence and you dont have much of it. Your boss or your wife and kids aren’t going to be impressed because you worked OT for 2 weeks learning how to wiz around some cryptic OSS like Kevin Mitnick phreaking a telco switch. The time spent getting to that point may not be worth it or you may not even have it. In many cases “pretty, paid for” equate to steep learning curve, ease of use and maintenance and good support. They also may mean less stress and more time for life’s more important things. It really comes down to making a good business decision that will help your business to succeed, not a decision based on ego that makes you think your The Brain.

Monday, December 04, 2006 5:38:37 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Thursday, November 30, 2006

You cant do it... Didnt realize this since I wouldnt normally do that (for performace reasons). But I was attaching an MDF that happened to be in my temp folder, which is compressed, and got the error. I didnt quite get it at first since I didnt realize this was not possible in 2005 and because I forgot that folder was compressed... :P You can however do this if the file is in a readonly file group or if you are attaching a readonly database.

The file "D:\temp\test.mdf" is compressed but does not reside in a read-only database or filegroup. The file must be decompressed.
CREATE DATABASE failed. Some file names listed could not be created. Check related errors. (Microsoft SQL Server, Error: 5118)

Thursday, November 30, 2006 5:00:45 AM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Wednesday, November 22, 2006

So I'm implementing an interface, defined in an assembly written in VB.NET, on a class in an assembly written in C#. The interface defines a number of events. VB.NET event declaration doesent require you to define the corresponding delegate (as C# does) so the question is where does the VB.NET compiler declare it for you after compilation? Well it seems that the delegate definition is declared right in the interface. This could be confusing for someone who doesent know VB.NET since C# does not allow the declaring of types within an interface whereas VB.NET does.

Here IDataInputDevice is an interface residing in an assembly written in VB.NET with three events defined. The corresponding delegate definitions are defined right within the interface.

.NET | C# | VB.NET
Wednesday, November 22, 2006 11:39:52 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Monday, November 20, 2006

I was looking over a code sample for reading from/writing to a serial port here at the MS support site. The VB.NET sample creates a SerialPort object within a using statement but then explicitly closes the SerialPort which is kind of an oxymoron. After doing a little investigation I found that the SerialPort class inherits from the Component class which implements IDisposable. The Dispose method in the Component class calls the Dispose(bool disposing) method which is overriden by the SerialPort class. The overriden method closes the SerialPort. In fact the Close method just turns around and calls this overriden method. Long story short, SerialPort.Dispose closes the serial port, so no need to explicitly close it within a using statement.

Reflected Component.Dispose method:

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

Reflected SerialPort.Dispose method:

protected override void Dispose(bool disposing)
{
    if (disposing && this.IsOpen)
    {
        this.internalSerialStream.Flush();
        this.internalSerialStream.Close();
        this.internalSerialStream = null;
    }
    base.Dispose(disposing);
}

Monday, November 20, 2006 11:02:38 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Tuesday, November 14, 2006

I ran into an issue where I could not enable the VMRC in MS Virtual Server 2005. I would check the box and save the settings but it would revert right back to being disabled. Turns out that VNC server happens to run on the same port, 5900, as the VMRC. So if you are running VNC you have to change the port for either VNC or VMRC. I wish the control panel would have just thrown an error but it's those sort of things that keep life interesting... ;-)

Tuesday, November 14, 2006 4:41:01 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [1]  | 
Friday, November 10, 2006

One of the shortcuts of C# (And now in VB.NET 2005) I love is the using statement. For those not familiar with it, it allows you to create objects within the scope of the using block and then once the block completes execution, calls the Dispose method on all the specified objects if they implement IDisposable. This occurs even if an exception is thrown. From what I understand, the using block in the resulting IL is a try/finally block, where the object disposal takes place in the finally.

This is perfect for working with a DataReader and instances where we want to make sure a database connection is closed right after a call. Since the Dispose method on a DataReader and Connection object call their own Close method they will be implicitly closed when we exit the using block, regardless of errors.

string ConnectionString = "server=127.0.0.1;database=duwamish7vb;Trusted_Connection=true";

using (SqlConnection Conn = new SqlConnection(ConnectionString))
{

    Conn.Open();

    SqlCommand Command = new SqlCommand("SELECT Name FROM Authors",Conn);

    using (SqlDataReader Reader = Command.ExecuteReader())
    {

        Authors.DataTextField = "Name";
        Authors.DataSource = Reader;
        Authors.DataBind();

    }

    Command = new SqlCommand("SELECT Subject FROM Books", Conn);

    using (SqlDataReader Reader = Command.ExecuteReader())
    {

        Books.DataTextField = "Subject";
        Books.DataSource = Reader;
        Books.DataBind();

    }

}

.NET | C# | VB.NET
Friday, November 10, 2006 9:17:27 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 

I have seen a lot of debate about VB.NET and C# and which one is "better". Before I started coding in C# I had some prejudice about it, but it’s interesting to see how my viewpoint has in some cases changed, and in others not changed after making the switch.

My viewpoint before switching over:

  • .NET languages are as MS put it a "lifestyle choice".
  • Many C# programmers think a little too much of themselves, projecting an elitist status as if a VB.NET developer knows nothing about OOD/OOP, design patterns and are just script kiddies.
  • Case sensitivity within a language is moronic, inelegant and causes ambiguity.
  • VB.NET is a very expressive language, like reading a book whereas C# looks like a bunch of ugly symbols.
  • And what’s with that stupid semi-colon anyway??

My viewpoint after switching over:

  • I still think it’s a lifestyle choice. I’m sure some C# purists will probably say I "don’t know enough about C#" or "that sounds like something a VB programmer would say". :-) The power of the .NET framework is, in my opinion, expressed well in both languages except for a few things here and there. Especially now with the release of v2.0 it’s not about whether or not you use a particular language syntax, it’s really about knowing how to develop .NET applications and about programming and design principles.
  • I still think some C# programmers think too much of themselves. I do realize however that the majority of VB.NET programmers come from the VB6/VBScript world, a world I am from. Many of those individuals carry a lot of baggage with them and do not have a good grasp of OO, design patterns, etc and are just not skilled developers. Many of them are the script kiddie type because it was so easy to pound out code in those languages, didnt require a whole lot of skill. But don’t judge a book by its cover. I think there are a lot of developers who came from that world who have embraced the principles, now present in the .NET framework (Not just a particular language syntax), that Java and C++ programmers have practiced and enjoyed for years.
  • I've not noticed the case sensitivity in C#… In fact in cases where I have not had VS prettying up my VB code I manually format my code anyway. Not even an issue. Ambiguity is definitely a possibility but I think a good developer would avoid that for clarity.
  • I actually now like all those "ugly symbols" over the expressive and verbose VB syntax… Very strange because that was one of my biggest prejudices aside from case sensitivity. It’s just a lot simpler and once you get used to it it’s not hard to read. If you are only familiar with the expressive syntax of VB it is hard to follow. I feel like I have much more flexibility over how I structure my code. Even going back to do maintenance on VB.NET code is less than enjoyable now that I have been working with C#.
  • Ok, the semi-colon is a little annoying at first but you get to the point where you don’t even think about it. It’s actually very nice in instances where you have a large string literal or a long line of code.

Bottom line is, "...just listen to your heart. That's what I always do". Dont be caught up in the hype that coding in VB.NET makes you a script kiddie. But I would seriously recomend, if you are a VB.NET developer who has not learned C#, to at least give it a try. You might be very surprised at how much you like the syntax over VB.

.NET | C# | VB.NET
Friday, November 10, 2006 8:25:01 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Wednesday, November 08, 2006

Previously (Prior to v1.4) the Subversion server (svnserve.exe) couldn’t be natively run as a Windows service. You had to use a wrapper such as srvany.exe from the Windows res kit to host it. Well now as of v1.4 it will run as a service but you have to manually install it. Doing this is pretty simple; just use the sc utility to add it at the command line as follows. The first svnserve switch (--service) notifies it that it should communicate with the SCM. The second (-r), which is optional, allows you to specify the root repository path.

C:\>sc create SubversionServer binpath= "\"C:\Program Files\Subversion\bin\svnserve.exe\" --service -r  e:\Subversion\RootRepo" displayname= "Subversion Server" depend= Tcpip start= auto

C:\>sc start SubversionServer

You can find the release notes about this new feature here.

Wednesday, November 08, 2006 12:01:14 AM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  | 
Tuesday, November 07, 2006

I ran into an issue today where I was coding in a class under a particular namespace but couldn’t access a class in another namespace that only differed by its namespace root. Here is what it looked like:

MyApp.Common.MyClass // Class I want to reference (For a unit test)

TestSuite.MyApp.Common.MyClass // the class I'm coding in (A unit test...)

When I referenced MyApp.Common.MyClass it was actually resolving to TestSuite.MyApp.Common.MyClass. So if you want to reference the former, you need to use the "global::" prefix as follows:

global::MyApp.Common.MyClass

.NET | C#
Tuesday, November 07, 2006 8:49:11 PM (GMT Standard Time, UTC+00:00)  #   |  Comments [0]  |