Subversion Repositories DevTools

Rev

Rev 5287 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<#
.SYNOPSIS
This Powershell script will replicate Repos from a Master Server
 
.DESCRIPTION
        This Powershell script will setup slave Repos from a specified
    Master.

    Assumption: The slave Repos will be setup on the current machine

        It will
                Scan the Repos on the Master
        Determine those that are mastered on the master (ignore non Master Repos)
        Determine those Repos not on the current machine
        Setup as Slave Replicas those Repos that are not on the current machine
            Add this machine to the Masters list of replicators
            Create the Repo and link it to the Master
            Copy in hook files from the master

.PARAMETER  Master
Name of new the master server

.EXAMPLE
ReplicateRepos.ps1 -Master MasterMachine
 
.NOTES
Uses a number of cmdlets provided by VisualSVN.
 
#>
#

#

Param
(
    [ parameter (Mandatory=$true,
                                 HelpMessage="Enter the name of the Master Repository server")]
    [string] $MASTER
)

#
# Get Data about a named Repo on the local machine
#
function GetRepoInfo( $repoName )
{
    $repoData = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Repository | Where { $_.Name -eq $repoName } 
    Return $RepoData
}

#
#   Get information on a named repo on the named Computer
function GetRemoteRepoInfo( $repoName, $ComputerName )
{
    $repoData = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Repository -ComputerName $ComputerName | Where { $_.Name -eq $repoName } 
    Return $RepoData
}

#
# Convert Absolute Path to UNC on a named computer
#
Function AbsToUnc( $ComputerName, $absPath )
{
    return '\\' + $ComputerName + '\' + $absPath.Replace(":","$")
}

#
#   Verify that the Master exists
#   
$masterSession = New-CimSession $MASTER -ErrorAction Ignore
If($masterSession -eq $null)
{
    Write-Error "The named computer ($MASTER) does not exist" -Category InvalidArgument
    Exit    
}

#
#   Get a list of all Repos Mastered on the Master
#
Get-SvnRepository -CimSession  $masterSession | Where { $_.Type -eq 'VdfsMaster' } | ForEach-Object {
    #
    #   See if the Repo exists locally
    #
    $repoName = $_.Name
    $repoData = Get-SvnRepository $repoName -ErrorAction SilentlyContinue
    if ($repoData -ne $null)
    {
        Write-Host ("{0,20} : {1}" -f $repoName, 'Already Exists')
        Return
    }

    #
    # Get a list of Replication Slaves for the Repo
    #
    $repoRepData = Get-SvnRepositoryReplication $repoName -CimSession $masterSession
    $replicators = $repoRepData.Replicators + "$env:COMPUTERNAME$"
    Set-SvnRepositoryReplication $repoName -Replicators $replicators -CimSession  $masterSession

    #
    #   Create the Repo
    #   Connect it to the Master
    #
    Write-Host ("{0,20} : {1}" -f $repoName, 'Creating Replica')
    $newRepo = New-SvnRepository $_.Name -Type VdfsSlave -MasterServer $MASTER

    #
    # Get Data about the new Repo
    # Need the Repo disk address
    #
    $repoInfo = GetRepoInfo $repoName
    If ($repoInfo -eq $null )
    {
        Write-Error 'Cannot fetch Repo Info for created Repo: $repoName'
        Return
    }
    $HookDst = $repoInfo.Path

    #
    # Determine the source of the hooks
    #
    $masterRepo = GetRemoteRepoInfo $repoName $MASTER
    $masterHookPathUnc = AbsToUnc $MASTER  ($masterRepo.Path  + '\hooks')
    $specialHooks = Test-Path ($masterHookPathUnc + '\specialhooks')
    Write-Host ("{0,20} : {1}" -f $repoName, "Master Hooks: $masterHookPathUnc")
    #Write-Host ("{0,20} : {1}" -f $repoName, "Special Hooks: $specialHooks")
    
    $HookSrc = $masterHookPathUnc
    #Write-Host "HookDst: $HookDst"
    #Write-Host "HookSrc: $HookSrc"
    $HookFileCount = 0
    Get-ChildItem $HookSrc -Filter '*.cmd' | ForEach-Object {
        $srcFile = $_.Name
        Write-Host ("{0,20} : {1}" -f $repoName, "Copy Hook: $srcFile")
        Copy-Item $_.FullName -Destination ($HookDst + '/hooks') 
        $HookFileCount++
    }
    If ($HookFileCount -eq 0 )
    {
        Write-Host ("{0,20} : {1}" -f $repoName, "Warning: No Hook files found in the current Repository Store")
    }
    If ($specialHooks)
    {
        Write-Host ("{0,20} : {1}" -f $repoName, "Copy specialhooks")
        Copy-Item ($HookSrc + '\specialhooks') -Destination ($HookDst + '/hooks') 
    }
}