← Back to team overview

mvhub-dev team mailing list archive

[Branch ~mvhub-dev/mvhub/trunk] Rev 367: merged improve_brave_add_dev_2010-04-16

 

Merge authors:
  Dan MacNeil (omacneil)
Related merge proposals:
  https://code.launchpad.net/~omacneil/mvhub/improve_brave_add_dev_2010-04-16/+merge/23633
  proposed by: Dan MacNeil (omacneil)
  review: Needs Fixing - Lee Goodrich (leegoodrich)
------------------------------------------------------------
revno: 367 [merge]
committer: Dan MacNeil <dan@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2010-04-23 16:19:35 -0400
message:
  merged improve_brave_add_dev_2010-04-16 
modified:
  app-mvhub/doc/checklists/setup_developer_on_brave.txt
  app-mvhub/project-tools/bin/mv_setup
  app-mvhub/project-tools/bin/mv_su_test
  lib-mvhub/lib/MVHub/Utils/ConfigSimple.pm


--
lp:mvhub
https://code.launchpad.net/~mvhub-dev/mvhub/trunk

Your team mvhub-dev is subscribed to branch lp:mvhub.
To unsubscribe from this branch go to https://code.launchpad.net/~mvhub-dev/mvhub/trunk/+edit-subscription
=== modified file 'app-mvhub/doc/checklists/setup_developer_on_brave.txt'
--- app-mvhub/doc/checklists/setup_developer_on_brave.txt	2010-03-08 08:07:29 +0000
+++ app-mvhub/doc/checklists/setup_developer_on_brave.txt	2010-04-19 02:04:58 +0000
@@ -22,7 +22,7 @@
 __ do the bits that are automated (dir & db setup)
 
         cdw 
-        mv_setup $NEW_DEV_USER
+        sudo app-mvhub/project-tools/bin/mv_setup $NEW_DEV_USER
 
 ___ Setup user's bazaar repository		
 		
@@ -84,7 +84,6 @@
 			
                        sudo chown -R $NEW_DEV_USER:$NEW_DEV_USER \
                        /home/$NEW_DEV_USER/.bazaar
-
 	
 	___ Create user's .ssh config file
 		
@@ -99,102 +98,21 @@
 		# Set the permissions
 		sudo chown $NEW_DEV_USER:$NEW_DEV_USER /home/$NEW_DEV_USER/.ssh -R
 	
-	
-	___ Create user's muttrc file
-	
-                cdw
-                cd app-mvhub/project-tools/developer_home_dir/
-                sudo cp muttrc /home/$NEW_DEV_USER/.muttrc
-		
-		# Edit the muttrc file
-               sudo $EDITOR /home/$NEW_DEV_USER/.muttrc
-		
-		# Change 'set pgp_sign_as="0x1234ABCD"' to be assigned to the 
-		# new user's pgp key. This is probably not setup at this point, 
-		# and will have to be revisited after the user creates their pgp
-		# key. set the 'set from="$YOUR_EMAIL_ADDRESS" to be assigned to 
-		# the user's email address.
-		
-		# Set the permissions
-		
-		sudo chown $NEW_DEV_USER:$NEW_DEV_USER \
-                   /home/$NEW_DEV_USER/.muttrc 		
-		
-___ copy conf templates
-
-        cd $BASE_DIR
-	
-        sudo cp link-to-live-code/app-mvhub/project-tools/templates/template.conf $BASE_DIR/conf/nsp.conf
-        sudo cp link-to-live-code/app-mvhub/project-tools/templates/template.conf $BASE_DIR/conf/mvh.conf
-
-        sudo chown $NEW_DEV_USER.$NEW_DEV_USER $BASE_DIR/conf/ -R
-        sudo chmod u=rw,g=rw,o= $BASE_DIR/conf -R
-        sudo chmod u=rwx,g=rwxs,o= $BASE_DIR/conf 
-	
-
-___ edit mvh.conf
-
-  cd $BASE_DIR/
-
-  # replace any keys that start with BAD_
-  # with ones that make sense
-  sudo $EDITOR conf/mvh.conf 
-
-
-[DATABASE]
-    database_host=localhost
-    database_name=$NEW_DEV_USER.mvh
-    database_user=$NEW_DEV_USER
-    # the database user's p---word
-    database_magic_word=$DEV_USER_PASSWORD
-
-[NOTIFICATION]
-admin_email=$NEW_DEV_USER@xxxxxxxxxx
-dev_email=$NEW_DEV_USER@xxxxxxxxxx
-
-___ edit nsp.conf  
-
-  # replace any keys that start with BAD_
-  # with ones that make sense
-sudo $EDITOR conf/nsp.conf
-
-[DATABASE]
-    database_host=localhost
-    database_name=$NEW_DEV_USER.nsp
-    database_user=$NEW_DEV_USER
-    # the database user's p---word
-    database_magic_word=$DEV_USER_PASSWORD
-
-[NOTIFICATION]
-admin_email=$NEW_DEV_USER@xxxxxxxxxx
-dev_email=$NEW_DEV_USER@xxxxxxxxxx
-    
 ___ setup apache basic auth
 	
         sudo htpasswd -cb  $BASE_DIR/conf/auth_apache_users test test
         sudo chown $NEW_DEV_USER:$NEW_DEV_USER $BASE_DIR/conf/auth_apache_users
 
-___ configure apache with test host names
-
-   # follow obvious pattern in file
-   sudo $EDITOR /etc/apache2/sites-available/mvhub_developer.data
-
-__ configure dns (if running on brave)
-
-  # follow obvious pattern in file
-  sudo $EDITOR /etc/bind/db.testing123.net
-  sudo dnssync
-
-___ restart apache
+___ restart apache & dns
 
 	sudo apache2ctl graceful
-
+        sudo dnssync
+        
 ___ touch log files so tests that look for them find them
 
 	sudo touch /var/www/mvhub/$NEW_DEV_USER/log/nsp/error.log
 	sudo touch /var/www/mvhub/$NEW_DEV_USER/log/mvh/error.log
 	
-
 ___ run tests & fix problems they show
 
         cdw

=== modified file 'app-mvhub/project-tools/bin/mv_setup'
--- app-mvhub/project-tools/bin/mv_setup	2010-04-06 20:52:15 +0000
+++ app-mvhub/project-tools/bin/mv_setup	2010-04-23 20:12:38 +0000
@@ -2,117 +2,146 @@
 
 # Purpose: automate setup / updaing of developer setup on brave
 
+# after modifiying test with:
+#      sudo mv_setup $OTHER_USER_THAT_EXISTS
+#      sudo mv_setup $NEW_USER
+#      mv_setup
+
 use strict;
 use warnings;
+use English qw/-no_match_vars/;
+
 use Carp;
 use DBI;
+use File::Copy qw/move/;
 use IO::Prompt;
 use Config::Simple;
 use MVHub::Utils::ConfigSimple;
+use MVHub::Utils::DB qw/get_dbh/;
 
-use English '-no_match_vars';
+my @WEBSITE_CODES = qw/ mvh nsp /;
 
 {    # main
- local $OUTPUT_AUTOFLUSH=1;
-	    
+    local $OUTPUT_AUTOFLUSH = 1;
+
     my $USERNAME = get_username_or_die();
-	my $cfg = MVHub::Utils::ConfigSimple::create_config_from($ENV{MV_CONFIG_FILE});
-	my @WEBSITE_CODES = qw/ mvh nsp /;
-	
-	my $base_dir = $cfg->param('BASE.dir');
-    
-    # should have nothing left on command line
-    # at this point
-    die usage() if scalar @ARGV;
+    die_if_bad_env_for($USERNAME);
+
+    my $cfg =
+      MVHub::Utils::ConfigSimple::create_config_from( $ENV{MV_CONFIG_FILE} );
 
     system('clear');
-    
-    print "(re)making dirs in $base_dir$USERNAME...";
+
+    my $base_dir = $cfg->param('BASE.dir');
     my @dirs = get_dirs_with( "$base_dir", $USERNAME );
     make_dirs_from( $USERNAME, \@dirs );
-    print "..done\n";
-
-    my $prompt = "DESTROY and reload databases for $USERNAME (Y/N):";
-    if ( IO::Prompt::prompt( $prompt, -YN ) ) {
-
-        die "I refuse to destroy production database data"
-          if $USERNAME =~ /www-data|production/;
-
-        print "(re)making databases for $USERNAME this may take 50 seconds....\n";
-        my $DBH = get_dbh();
-
-        print "...done\n" 
-        	if make_dbs_for( $DBH, $USERNAME, @WEBSITE_CODES );;
-    }
-    create_config_files_for($USERNAME, $cfg, @WEBSITE_CODES);
-}
-
-sub add_calculable_values{
-	my $template_cfg = shift or croak 'missing param: $template_cfg';
-	my $username = shift or croak 'missing param: $username';
-	my $site_code = shift or croak 'missing param: $site_code';
-	
-	$template_cfg->param('DATABASE.database_name',"$username.$site_code");
-	$template_cfg->param('DATABASE.database_user',"$username");
-	$template_cfg->param('NOTIFICATION.admin_email', "$username\@thecsl.org");
-	$template_cfg->param('NOTIFICATION.dev_email', "$username\@thecsl.org");
-	$template_cfg->param('SITE.website_name',"$site_code.$username.testing123.net");
-	$template_cfg->param('SITE.website_code',"$site_code");
-	
-	return $template_cfg;
-}
-
-sub add_site_specific_values{
-	my $template_cfg = shift or croak 'missing param: $template_cfg';
-	my $username = shift or croak 'missing param: $username';
-	my %site_specific_values = %_;
-	
-	foreach my $key (keys %site_specific_values){
-		$template_cfg->param($key, $site_specific_values{$key});
-	}
-	return $template_cfg;
-}
- 
-sub add_user_generated_values{
-	my $template_cfg = shift or croak 'missing param: $template_cfg';
-	my $user_cfg = shift or croak 'missing param: $user_cfg';
-	my @keys = @_;
-
-	foreach my $key (@keys){
-		if (!($user_cfg->param($key))){
-			prompt("Please enter a value for $key: ");
-			$template_cfg->param($key,$_);
-		}
-	}
-	return $template_cfg;
-}
-
-sub create_config_files_for{
-	my $username = shift;
-	my $cfg = shift;
-	my @website_codes = @_;
-	my @keys_for_user_generated_values = qw/ DATABASE.database_magic_word /;
-	
-	my $base_dir = $cfg->param('BASE.dir');	
-	my $template_cfg = new Config::Simple($cfg->param('ABSOLUTE_PATH.template_conf_dir') . "/template.conf");	
-	
-	foreach my $site_code (@website_codes){
-		my $user_cfg = new Config::Simple(syntax=>'ini');
-		if (-e "$base_dir/$username/conf/$site_code.conf") {
-			$user_cfg-> read("$base_dir/$username/conf/$site_code.conf");	
-		}
-		
-		print "Editing Config: $base_dir/$username/conf/$site_code.conf\n";
-		my %site_specific_values = get_site_specific_values($site_code);
-		
-		$template_cfg = add_site_specific_values($template_cfg, $username, %site_specific_values);
-		$template_cfg = add_calculable_values($template_cfg, $username, $site_code);
-		$template_cfg = add_user_generated_values($template_cfg, $user_cfg, @keys_for_user_generated_values);
-		
-		merge_conf_objects($template_cfg, $user_cfg);
-		
-		$user_cfg->write("$base_dir/$username/conf/$site_code.conf");
-	}
+
+    make_databases_for( $USERNAME, @WEBSITE_CODES );
+
+    make_config_files_for( $USERNAME, $cfg, @WEBSITE_CODES );
+    
+    if (defined $ENV{SUDO_USER}){
+       foreach my $prefix (@WEBSITE_CODES){
+          add_dns($USERNAME,$prefix);
+          add_apache_config($USERNAME,$prefix);
+       }
+    }
+}
+
+sub add_dns {
+    my $username = shift or croak 'missing paramater: $username';
+    my $prefix   = shift or croak 'missing parameter: $prefix';
+
+    my $host="$prefix.$username";
+    my $FILE='/etc/bind/db.testing123.net';
+        
+    my $line = sprintf( "%-15s IN      A       129.63.96.180\n", $host);
+    if (possible_dup_line($host,$FILE)){
+       warn "$host found in $FILE, skipping append\n";
+       return;
+    }
+
+    append_to_file( $FILE, $line );
+}
+
+sub add_apache_config {
+    my $username = shift or croak 'missing paramater: $username';
+    my $prefix   = shift or croak 'missing parameter: $prefix';
+
+    my $FILE     = '/etc/apache2/sites-available/mvhub_developer.data';
+    my $host     = "$prefix.$username.testing123.net";
+    
+    my $line = sprintf( "Use MVhub %-15s $prefix $host\n", $username 
+    );
+
+    if (possible_dup_line($host,$FILE)){
+       warn "$host found in $FILE, skipping append\n";
+       return;
+    }
+
+    append_to_file( $FILE, $line );
+}
+
+sub append_to_file {
+    my ( $file, $append_lines ) = @_;
+    my $tmp_file = "$file.tmp";
+
+    open( IN, $file )
+      or die "bad open: $file  error: $! \n";
+    my @lines = <IN>;
+    close(IN) or die "bad close $file error: $!\n";
+
+    push @lines, $append_lines;
+
+    open( OUT, ">", "$tmp_file" )
+      or die "couldn't open $tmp_file.tmp error: $! \n";
+    ( print OUT @lines )
+      or die "couldn't write to $tmp_file $!\n";
+
+    close(OUT) or die "couldn't close $tmp_file $!\n";
+    File::Copy::move( $tmp_file, $file )
+      or die "couldn't rename $tmp_file to $file\n";
+}
+
+sub add_calculable_values {
+    my $template_cfg = shift or croak 'missing param: $template_cfg';
+    my $username     = shift or croak 'missing param: $username';
+    my $site_code    = shift or croak 'missing param: $site_code';
+
+    $template_cfg->param( 'DATABASE.database_name',   "$username.$site_code" );
+    $template_cfg->param( 'DATABASE.database_user',   "$username" );
+    $template_cfg->param( 'NOTIFICATION.admin_email', "$username\@thecsl.org" );
+    $template_cfg->param( 'NOTIFICATION.dev_email',   "$username\@thecsl.org" );
+    $template_cfg->param( 'SITE.website_name',
+        "$site_code.$username.testing123.net" );
+    $template_cfg->param( 'SITE.website_code', "$site_code" );
+
+    return $template_cfg;
+}
+
+sub add_site_specific_values {
+    my $template_cfg = shift or croak 'missing param: $template_cfg';
+    my $username     = shift or croak 'missing param: $username';
+    my %site_specific_values = %_;
+
+    foreach my $key ( keys %site_specific_values ) {
+        $template_cfg->param( $key, $site_specific_values{$key} );
+    }
+    return $template_cfg;
+}
+
+sub add_user_generated_values {
+    my $template_cfg = shift or croak 'missing param: $template_cfg';
+    my $user_cfg     = shift or croak 'missing param: $user_cfg';
+    my @keys         = @_;
+
+    foreach my $key (@keys) {
+        if ( !( $user_cfg->param($key) ) ) {
+            prompt("Please enter a value for $key: ");
+            $template_cfg->param( $key, $_ );
+        }
+    }
+    return $template_cfg;
 }
 
 sub db_exists {
@@ -164,11 +193,12 @@
      rolname = ?
 SQL
 
-    my $role_rows_aref = $dbh->selectall_arrayref( $sql, {Slice =>{} }, ($username) );
+    my $role_rows_aref =
+      $dbh->selectall_arrayref( $sql, { Slice => {} }, ($username) );
     my $result = $$role_rows_aref[0]{rolcreaterole}
       && $$role_rows_aref[0]{rolcreatedb};
 
-    return $result ? 1 :0;
+    return $result ? 1 : 0;
 }
 
 sub db_user_has_superuser_role {
@@ -184,8 +214,9 @@
      rolname = ?
 SQL
 
-    my $role_rows_aref = $dbh->selectall_arrayref( $sql, {Slice=>{}}, ($username) );
-    return $$role_rows_aref[0]{rolsuper} ? 1:0;
+    my $role_rows_aref =
+      $dbh->selectall_arrayref( $sql, { Slice => {} }, ($username) );
+    return $$role_rows_aref[0]{rolsuper} ? 1 : 0;
 }
 
 sub do_or_die {
@@ -196,21 +227,6 @@
       or die "$cmd failed ABORTING\n";
 }
 
-# depends a lot on brave.thecsl.org enviroment
-sub get_dbh {
-
-    my %attr = (
-        'PrintError'         => 0,
-        'RaiseError'         => 1,
-        'AutoCommit'         => 1,
-        'ShowErrorStatement' => 1,
-    );
-    my $dbh = DBI->connect( 'dbi:Pg:dbname=template1', '', '', \%attr )
-      or die "couldn't connect to database";
-
-    return $dbh;
-}
-
 sub get_dirs_with {
     my $base_dir = shift or croak 'missing param: $base_dir';
     my $username = shift or croak 'missing param: $username';
@@ -275,19 +291,56 @@
     return @dirs;
 }
 
-sub get_site_specific_values{
-	my $site_code = shift or croak 'missing param: $site_code';
-
-	my %hash_of_site_specific_values = (
-	'mvh' => { 
-		'SITE.location' => '"Massachusetts Merrimack Valley"', 
-		'SITE.website_description' => 'Merrimack Valley Hub',
-		'NOTIFICATION.team_name' => 'Merrimack Valley Hub Team'},
-	'nsp' => {
-		'SITE.location' => '"Massachusetts North Shore"', 
-		'SITE.website_description' => 'North Shore Portal',
-		'NOTIFICATION.team_name' => 'North Shore Portal Team'});
-	return %{$hash_of_site_specific_values{$site_code}};
+sub get_site_specific_values {
+    my $site_code = shift or croak 'missing param: $site_code';
+
+    my %hash_of_site_specific_values = (
+        'mvh' => {
+            'SITE.location'            => '"Massachusetts Merrimack Valley"',
+            'SITE.website_description' => 'Merrimack Valley Hub',
+            'NOTIFICATION.team_name'   => 'Merrimack Valley Hub Team'
+        },
+        'nsp' => {
+            'SITE.location'            => '"Massachusetts North Shore"',
+            'SITE.website_description' => 'North Shore Portal',
+            'NOTIFICATION.team_name'   => 'North Shore Portal Team'
+        }
+    );
+    return %{ $hash_of_site_specific_values{$site_code} };
+}
+
+sub die_if_bad_env_for {
+    my $username = shift or croak 'missing parameter $username\n';
+    my $msg = '';
+
+    foreach my $var (qw/PERL5LIB MV_CONFIG_FILE/) {
+        $msg .= "$var not set"
+          if !defined $ENV{$var};
+    }
+
+    my $xtra_msg = <<'HERE';
+     if running with sudo edit /etc/sudoers to include line:
+
+        Defaults     env_keep+="PERL5LIB MV_CONFIG_FILE"
+
+    also be sure you ran:
+    
+        cdw
+HERE
+
+    if ($msg) {
+        $msg .= $xtra_msg;
+    }
+
+    $msg .= "\nneed to run under sudo if you aren't $username\n"
+      if ( $username ne $ENV{USER} && $EFFECTIVE_USER_ID != 0 );
+
+    $msg .=
+"\ncan't run mv_setup for user root, did you forget a \$user param on command line?\n"
+      if $username eq 'root';
+
+    die $msg if $msg;
+    return 1;
 }
 
 sub get_username_or_die {
@@ -305,6 +358,10 @@
         die "'$username' is not a valid username" . usage();
     }
 
+    # should have nothing left on command line
+    # at this point
+    die usage() if scalar @ARGV;
+
     return $username;
 }
 
@@ -312,13 +369,12 @@
     my $dbh      = shift or croak 'missing param: $dbh';
     my $username = shift or croak 'missing param: $username';
     my $suffix   = shift or croak 'missing param:   $db_name';
-	
-	my $cfg = 
-	  MVHub::Utils::ConfigSimple::create_config_from($ENV{MV_CONFIG_FILE});
-
-	my $path_to_project_tools = $cfg->param('ABSOLUTE_PATH.project_tools_dir');
-	my $db_password = $cfg->param('DATABASE.database_magic_word');
-	
+
+    my $cfg =
+      MVHub::Utils::ConfigSimple::create_config_from( $ENV{MV_CONFIG_FILE} );
+
+    my $path_to_project_tools = $cfg->param('ABSOLUTE_PATH.project_tools_dir');
+    my $db_password           = $cfg->param('DATABASE.database_magic_word');
 
     my $cmd = "export PGPASSWORD=$db_password ";
     $cmd .= "&& psql -h localhost -U $username -d  $username.$suffix ";
@@ -329,22 +385,62 @@
 
 }
 
+sub make_config_files_for {
+    my $username                       = shift;
+    my $cfg                            = shift;
+    my @website_codes                  = @_;
+    my @keys_for_user_generated_values = qw/ DATABASE.database_magic_word /;
+
+    my $base_dir = $cfg->param('BASE.dir');
+    my $template_config_file =
+      $cfg->param('ABSOLUTE_PATH.template_conf_dir') . "/template.conf";
+    my $template_cfg = new Config::Simple($template_config_file)
+      or die "failed to create config object from $template_config_file";
+
+    foreach my $site_code (@website_codes) {
+
+        my $cfg_file = "$base_dir/$username/conf/$site_code.conf";
+        my $user_cfg = new Config::Simple( syntax => 'ini' );
+        if ( !-e $cfg_file ) {
+            make_empty_config_file_named($cfg_file);
+        }
+        $user_cfg->read($cfg_file);
+
+        print "Editing Config: $cfg_file\n";
+        my %site_specific_values = get_site_specific_values($site_code);
+
+        $template_cfg = add_site_specific_values( $template_cfg, $username,
+            %site_specific_values );
+        $template_cfg =
+          add_calculable_values( $template_cfg, $username, $site_code );
+        $template_cfg = add_user_generated_values( $template_cfg, $user_cfg,
+            @keys_for_user_generated_values );
+
+        merge_conf_objects( $template_cfg, $user_cfg );
+
+        $user_cfg->write("$base_dir/$username/conf/$site_code.conf");
+    }
+}
+
 sub make_dbs_for {
     my $dbh      = shift or croak 'missing param: $dbh';
     my $username = shift or croak 'missing param: $username';
-	my @website_codes = @_;
-	
+    my @website_codes = @_;
+
     my $sql;
-
-    if ( !db_user_has_needed_roles( $dbh, $ENV{USER} ) ) {
-        warn "\nSkipping db stuff $ENV{USER} lacks CREATEDB or CREATEROLE\n";
+    my $user_running_cmd =
+      defined $ENV{SUDO_USER} ? $ENV{SUDO_USER} : $ENV{USER};
+    if ( !db_user_has_needed_roles( $dbh, $user_running_cmd ) ) {
+        warn
+"\nSkipping db stuff $user_running_cmd lacks CREATEDB or CREATEROLE\n";
         return;
     }
 
-    if ( ( $ENV{USER} ne $username )
-        && !db_user_has_superuser_role($dbh,$ENV{USER}) ){
+    if ( ( $user_running_cmd ne $username )
+        && !db_user_has_superuser_role( $dbh, $user_running_cmd ) )
+    {
         my $msg = qq/
-        skipping db stuff $ENV{USER} can't drop table owned by $username 
+        skipping db stuff $user_running_cmd can't drop table owned by $username 
         without role SUPERUSER
         /;
         warn $msg;
@@ -356,20 +452,52 @@
         $dbh->do($sql);
     }
 
-    foreach my $suffix ( @website_codes ) {
+    foreach my $suffix (@website_codes) {
         if ( db_exists( $dbh, "$username.$suffix" ) ) {
             $sql = qq{DROP DATABASE "$username.${suffix}"};
             $dbh->do($sql);
         }
+
         # kludge to avoid 'db being currently being accessed' errs
-        sleep 1; 
+        sleep 1;
 
         $sql = qq{CREATE DATABASE "$username.${suffix}" OWNER $username};
         $dbh->do($sql);
 
         load_test_data_for( $dbh, $username, $suffix );
     }
-return 1;
+    return 1;
+}
+
+sub make_empty_config_file_named {
+    my $filename = shift or croak 'missing Param $filename';
+
+    open my $out_fh, '>', $filename
+      or die "failed to open $filename for writing error:$!\n";
+    print $out_fh "#Config file\n [ignore]\n";
+    close $out_fh
+      or die "failed to close $filename error:$!\n";
+    return 1;
+}
+
+sub make_databases_for {
+    my $username      = shift or croak 'missing parameter: $username';
+    my @website_codes = @_    or croak 'mssing parameter: @website_codes';
+
+    my $prompt = "DESTROY and reload databases for $username (Y/N):";
+    if ( IO::Prompt::prompt( $prompt, -YN ) ) {
+
+        die "I refuse to destroy production database data"
+          if $username =~ /www-data|production/;
+
+        print
+          "(re)making databases for $username this may take 50 seconds....\n";
+        my $DBH = MVHub::Utils::DB::get_dbh( $ENV{MV_CONFIG_FILE} );
+
+        print "...done\n"
+          if make_dbs_for( $DBH, $username, @website_codes );
+
+    }
 }
 
 sub make_dirs_from {
@@ -377,16 +505,6 @@
     my $dir_hrefs_href = shift or croak 'missing param: $dir_hrefs_href';
     my @dir_hrefs = @$dir_hrefs_href;
 
-    my $sudo_cmd;
-
-    # don't need sudo to modify in our own dir
-    if ( $username eq $ENV{USER} ) {
-        $sudo_cmd = '';
-    }
-    else {
-        $sudo_cmd = 'sudo ';
-    }
-
     foreach my $dir_href (@dir_hrefs) {
         my $mkdir_cmd = "mkdir -p $dir_href->{dir}";
         my $chown_cmd =
@@ -402,35 +520,68 @@
               "chown -R $dir_href->{owner}:$dir_href->{group} $dir_href->{dir}";
         }
         my $chmod_cmd = "chmod $dir_href->{permissions} $dir_href->{dir}";
-        do_or_die("$sudo_cmd $mkdir_cmd");
-        do_or_die("$sudo_cmd $chown_cmd");
-        do_or_die("$sudo_cmd $chmod_cmd");
+        do_or_die($mkdir_cmd);
+        do_or_die($chown_cmd);
+        do_or_die($chmod_cmd);
     }
 }
 
-sub merge_conf_objects{
-	my $template_cfg = shift or croak 'missing param: $template_cfg';
-	my $user_cfg = shift or croak 'missing param: $user_cfg';
-	
-	foreach my $key ($template_cfg->param()){
-
-		if (! ($user_cfg->param($key))){
-			$user_cfg->param($key, $template_cfg->param($key));
-		}
-	}	
-	return $user_cfg;
+sub merge_conf_objects {
+    my $template_cfg = shift or croak 'missing param: $template_cfg';
+    my $user_cfg     = shift or croak 'missing param: $user_cfg';
+
+    foreach my $key ( $template_cfg->param() ) {
+        if ( !( $user_cfg->param($key) ) ) {
+            my $value = $template_cfg->param($key);
+            $value = defined $value ? $value : 'BAD_MISSING';
+            $user_cfg->param( $key, $value );
+        }
+    }
+
+    #remove keys no longer used
+    foreach my $key ( $user_cfg->param() ) {
+        if ( !defined $template_cfg->param($key) ) {
+            $user_cfg->delete($key);
+        }
+    }
+
+    return $user_cfg;
 }
 
 sub usage {
-    return << "USAGE";
-
-Usage: 
- mv_setup <username>
-or:
+    return << 'USAGE';
+
+Usage to update your setup:
+
+   # to update your own developer setup
+   cdw && mv_setup
+
+   # to update parts of your developer setup 
+   # (apache & dns) that require root
+   cdw && sudo app-mvhub/project-tools/bin/mv_setup $USER
+
+Usage to update or partly create a developer setup for somebody else: 
+ 
+ # includes apache, & DNS
+ sudo app-mvhub/project-tools/bin/mv_setup <username>
+
+or: 
  export NEW_DEV_USER=<username> && mv_setup
-or:
- cdw && mv_setup
+ sudo app-mvhub/project-tools/bin/mv_setup
+
 USAGE
 
 }
 
+sub possible_dup_line{
+    my $host =shift or croak 'missing parameter: $host';
+    my $filename =shift or croak 'missing parameter: $filename';
+
+    open my $in_fh, $filename 
+    	or die "failed to open $filename error:$!";
+    
+    my @contents=<$in_fh>;
+    my $regex=qr/$host/;
+    return scalar grep {$_=~$regex} @contents;
+}
+

=== modified file 'app-mvhub/project-tools/bin/mv_su_test'
--- app-mvhub/project-tools/bin/mv_su_test	2009-06-24 17:59:08 +0000
+++ app-mvhub/project-tools/bin/mv_su_test	2010-04-18 20:31:28 +0000
@@ -22,11 +22,8 @@
     set_env_from(%env);
 
     # run tests
-    my $cmd = "mv_prove app-mvhub/t/ -r";
-    ( system($cmd) == 0 ) or die "Failed: $cmd \n";
-    $cmd = "mv_prove lib-mvhub/t/ -r";
-    ( system($cmd) == 0 ) or die "Failed: $cmd \n";
-
+    my $cmd = "mv_prove app-mvhub/t/ lib-mvhub/t/ -r";
+    ( system($cmd) == 0 ) or die "Failed: $cmd \n";
 }   #main
 
 sub die_on_bad {

=== modified file 'lib-mvhub/lib/MVHub/Utils/ConfigSimple.pm'
--- lib-mvhub/lib/MVHub/Utils/ConfigSimple.pm	2009-12-27 22:28:47 +0000
+++ lib-mvhub/lib/MVHub/Utils/ConfigSimple.pm	2010-04-18 20:51:33 +0000
@@ -45,12 +45,12 @@
     my $base_dir = $cfg->param('BASE.dir')
         or $error_msg
         .= "param: 'BASE.dir' not found in config file: '$config_file'\n";
-
     croak $error_msg if $error_msg;
 
+    my $user = defined $ENV{SUDO_USER} ? $ENV{SUDO_USER} : $ENV{USER};
     foreach my $path_name ( keys %$relative_paths_href ) {
         my $absolute_path
-            = "$base_dir/$ENV{USER}/$$relative_paths_href{$path_name}";
+            = "$base_dir/$user/$$relative_paths_href{$path_name}";
         $path_name =~ s|^RELATIVE_PATH\.||;
         $cfg->param( "ABSOLUTE_PATH.$path_name", $absolute_path );
     }