Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

<#
.SYNOPSIS
This Powershell script will change the Mastership of a SVN Repo
 
.DESCRIPTION
        This Powershell script will chnage the Mastership of a SVN Repo
        Assumtion: The Repo is present on the current machine

        It will
                Determine the location of the Master Repo
                Ask the Master for the list of Slave Repo servers
                Check that the new master is not the current master
                Check that the new master is one of the slave servers
                Reconfigure the Repos on all servers

.PARAMETER  Repo
Name of the Repo to re-master

.PARAMETER  NewMaster
Name of new the new master server

.PARAMETER      ComputerName
Name of computer to examne for repo
Default is the current computer

.EXAMPLE
ChangeMaster.ps1 -Repo MyRepo -NewMaster NewMaster
 
.NOTES
Uses a number of cmdlets provided by VisualSVN.
 
#>
#

#

Param
(
    [ parameter (Mandatory=$true,
                     HelpMessage="Enter the name of the new Master Server")]
    [string] $Repo,
    [ parameter (Mandatory=$true,
                                 HelpMessage="Enter the name of the Repository to be remastered")]
    [string] $NEWMASTER,
    [ parameter () ]
    [string] $ComputerName
)


Function Remaster-Repo( $REPO, $NEWMASTER)
{
    # Init Data
    $ALLSERVERS = @()

    #
    # Examine current machine and determine data about the repo
    #
    $argList = @{Namespace= 'root\VisualSVN' ; ClassName = 'VisualSVN_Repository'; ErrorVariable = 'gciError'}
    If ($ComputerName)
    {
        $testSession = New-CimSession $ComputerName -ErrorAction Ignore
        If($testSession -eq $null)
        {
            Write-Error "The named computer ($ComputerName) does not exist" -Category InvalidArgument
            Return    
        }
        Remove-CimSession $testSession
        $argList.Add('ComputerName', $ComputerName )
    }
    #Write-Host 'argList:' , ($argList | Format-List | Out-String)
    $repoData = Get-CimInstance @argList | where { $_.Name -eq $REPO }
    If ($repoData -eq $null )
    {
        Write-Error "The repo ($REPO) does not exist on the local machine" -Category InvalidArgument
        Return
    }
    #Write-Host 'RepoData:' , ($repoData | Format-List | Out-String)
    $CURMASTER = $repoData.MasterServer
    If (! $CURMASTER) { $CURMASTER = $env:COMPUTERNAME }
    Write-Host "Current Master:", $CURMASTER
    $CURMASTER = $CURMASTER.ToUpper()
    $NEWMASTER = $NEWMASTER.ToUpper()
    $ALLSERVERS += $CURMASTER

    If ( $NEWMASTER -eq $CURMASTER )
    {
                # This is not an error
        Write-Host "New Master is the same as the Current Master"
        Return
    }


    #
    # Examine the repo on the Master
    #
    $RepoData =  Get-SvnRepositoryReplication $REPO -CimSession $CURMASTER
    #Write-Host ($RepoData | Format-List | Out-String)
    $RepoData.Replicators | ForEach-Object {
        $name = $_ -match '\w+\\(\w+)'
        If ( $name )
        {
            $ALLSERVERS += $matches[1].ToUpper()
        }
        else
        {
            Write-Error "Replicator data in unexepcted form: $_" -Category InvalidData
            Return;
        }
    }
    Write-Host "All Servers:", $ALLSERVERS

    #
    # Test that new master is in the set of known servers
    #
    If ($ALLSERVERS -contains $NEWMASTER )
    {
        #   Build up a list of replicators
        #       All the server names, remove the new master, append '$' so that its the machine name
        # 
        $REPLICATORS =  $ALLSERVERS | where { $_ -ne $NEWMASTER } | ForEach-Object { $_ + '$' }

        #
        # Display stuff
        #
        Write-Host "New Master:", $NEWMASTER
        Write-Host "Replicators: ", $REPLICATORS

        #
        # Do the hard part
        #
        $ALLSERVERS | ForEach-Object { Suspend-SvnRepository -name $REPO -CimSession $_ }
        
        Switch-SvnRepository -Name $REPO -Role Master -Confirm:$false -CimSession $NEWMASTER

        Set-SvnRepositoryReplication $REPO -Replicators $REPLICATORS -CimSession $NEWMASTER
        Set-SvnRepositoryReplication $REPO -Enabled $true -CimSession $NEWMASTER

        Switch-SvnRepository -name $REPO -Role Slave -MasterServer $NEWMASTER -Confirm:$false -CimSession $CURMASTER
        
        $ALLSERVERS | Where { $_ -ne $NEWMASTER } | ForEach-Object {
            Set-SvnRepository $REPO -MasterServer $NEWMASTER  -Confirm:$false -CimSession $_
        }
        
        $ALLSERVERS | ForEach-Object { Resume-SvnRepository -name $REPO -CimSession $_ }
    }
    else
    {
        Write-Error "The new master ($NEWMASTER) is not one of the replicated slaves : $ALLSERVERS" -Category InvalidArgument
        Return
    }
 }

 #
 # Invoke the function
 #
 #Write-Host "Repo:", $REPO, "NewMaster:", $NEWMASTER
Remaster-Repo $REPO $NEWMASTER