Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(nexus-repository-migrator) Fixes Nexus 3.71 Breaking Change Upgrade #2519

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions automatic/nexus-repository-migrator/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Nexus Repository Migrator

## Features

In release 3.71.0, Sonatype Nexus Repository began using H2 as its default embedded database.
OrientDB is now in Extended Maintenance as defined in our [Sunsetting documentation](https://help.sonatype.com/en/sonatype-sunsetting-information.html).
Those wishing to upgrade to version 3.71.0 or above will need to migrate to either an H2 or PostgreSQL database.
See our detailed [help topic on Upgrading to 3.71.0 and beyond](https://help.sonatype.com/en/upgrading-to-nexus-repository-3-71-0-and-beyond.html).

This package contains the migrator tool to migrate a Sonatype Nexus Repository 3.70.1 database from OrientDb to H2 (available to all) or PostgreSQL (available to Pro license holders).

You can either install the package and run the migrator by following the instructions in Notes, or run the script `ConvertFrom-NexusOrientDb` in the tools directory.

If you have upgraded to the `nexus-repository` package version 3.71.0.6 and your installation is failing to run, you can run the `Repair-Nexus371FailedUpgrade` script in the tools directory.

## Package Parameters

This package supports the following parameters:

* `/Migrate` - Triggers migration of your existing Sonatype Nexus install(s) from OrientDb to a H2 database.
* `/FQDN` - The fully-qualified domain name that matches the subject you are using for your Nexus instance SSL certificate.

You can pass parameters as follows:

`choco install nexus-repository-migrator --parameters="/Migrate /FQDN=nexus.example.com"`

## Notes

**Please note that using the scripts contained within is entirely at the user's own risk. Read them before you run them!**

For more details, including how to migrate to PostgreSQL, see the [Migrating To A New Database article](https://help.sonatype.com/en/migrating-to-a-new-database.html).

### Migration Environment Prerequisite Requirements

The checklist below covers requirements for a successful database migration:

- If you are migrating from OrientDB to H2 or PostgreSQL, your OrientDB-based instance must be on the latest 3.70.x version.
- You must have JRE 8 or JRE 11 available. The Chocolatey `nexus-repository` 3.70.1.6 package contains this already.
- You must have at least 16GB RAM available.
- You must have a database backup in a clean working location.
- The migrator utility requires three times the disk space (minimum 10 GB) as your $data-dir/db directory.

### Migrating From OrientDB to H2

1. Perform a full backup using normal backup procedures.
1. Copy the backup to a clean working location on a different filesystem so that any extraction doesn’t impact the existing production system.
1. Shut down Nexus Repository.
1. Run the following command from the clean working location containing your database backup. You may include any of the optional parameters listed in the section below when running this command.
`java -Xmx16G -Xms16G -XX:+UseG1GC -XX:MaxDirectMemorySize=28672M -jar nexus-db-migrator-*.jar --migration_type=h2`
1. Copy the resultant nexus.mv.db file to your $data-dir/db directory.
1. Edit the $data-dir/etc/nexus.properties file and add the following line: `nexus.datastore.enabled=true`
1. Start Nexus Repository
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>nexus-repository-migrator</id>
<title>Nexus Repository Migrator</title>
<version>3.70.2.1</version>
<authors>Sonatype</authors>
<owners>chocolatey-community, jpruskin</owners>
<summary>Migrator for the Sonatype Nexus Repository database.</summary>
<description><![CDATA[]]></description>
<projectUrl>https://help.sonatype.com/en/orientdb-downloads.html</projectUrl>
<projectSourceUrl>https://github.com/sonatype/nexus-public</projectSourceUrl>
<docsUrl>https://help.sonatype.com/en/migrating-to-a-new-database.html</docsUrl>
<tags>nexus-repository-migrator utility freeware cross-platform sonatype nexus-repository</tags>
<copyright>Sonatype</copyright>
<licenseUrl>http://www.eclipse.org/legal/epl-v10.html</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<iconUrl>https://cdn.jsdelivr.net/gh/chocolatey-community/chocolatey-packages@f459e946d7b1926ee89c2b415ec8507dffe99218/icons/nexus-repository.png</iconUrl>
<releaseNotes>https://help.sonatype.com/repomanager3/release-notes</releaseNotes>
<dependencies>
<!--dependency id="nexus-repository" version="3.70.1.2" /-->
</dependencies>
</metadata>
<files>
<file src="tools\**" target="tools" />
<file src="..\nexus-repository\tools\helpers.ps1" target="tools\nexus-helpers.ps1" />
</files>
</package>
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<#
.Synopsis
Migrates Sonatype Nexus Repository 3.70.1-02 to the H2 database type

.Example
.\ConvertFrom-NexusOrientDb.ps1

.Example
.\ConvertFrom-NexusOrientDb.ps1 -JavaPath .\path\to\java.exe
#>
[CmdletBinding(SupportsShouldProcess)]
param(
# A path to a Java.exe file, major version 8 or 11.
[string]$JavaPath,

# The hostname of the machine used by Nexus, if using an SSL certificate.
[string]$Hostname,

# Forces migration even if the test doesn't think it is required.
[switch]$Force
)

Import-Module $PSScriptRoot\nexus-helpers.ps1 -Verbose:$false
JPRuskin marked this conversation as resolved.
Show resolved Hide resolved

foreach ($Service in Get-NexusRepositoryServiceInstall) {
if ($Force -or (Test-NexusMigratorRequired -DataDir (Split-Path $Service.DataFolder) -ProgramDir $Service.ProgramFolder)) {
Write-Host "Preparing for database migration..."
$MigrationFiles = Join-Path $env:Temp "dbmigration-$($Service.ServiceName)"
$MigratorDownload = @{FileFullPath = Join-Path $PSScriptRoot "nexus-db-migrator.jar"}
$PreMigrationIssues = @()

if (Test-NexusMigratorFreeSpaceProblem -Drive $MigrationFiles.Split(':')[0] -DatabaseFolder (Join-Path $Service.DataFolder "db")) {
$PreMigrationIssues += "Cannot migrate database with available disk space"
}

if (Test-NexusMigratorMemoryProblem) {
$PreMigrationIssues += "Cannot migrate database with available memory"
}

# Test if contained JRE is compatible, otherwise check JAVA_HOME, otherwise...
$JavaPath = @(
$JavaPath
Join-Path $Service.ProgramFolder "\jre\bin\java.exe"
Convert-Path $env:JAVA_HOME\bin\java.exe -ErrorAction SilentlyContinue
Convert-Path $env:ProgramFiles\*\jre-*\bin\java.exe -ErrorAction SilentlyContinue
) | Where-Object {
$_ -and
(Test-Path $_) -and
(([version](Get-ItemProperty -Path $_).VersionInfo.ProductVersion).Major -in 8, 11)
} | Select-Object -First 1

if (-not $JavaPath) {
$PreMigrationIssues += "Nexus Migrator requires JRE 8 or JRE 11. Please provide a -JavaPath to a compatible version."
}

if ($PreMigrationIssues) {
Write-Error -Message ($PreMigrationIssues -join "`n") -ErrorAction Stop
}

$ServiceState = (Get-Service $Service.ServiceName).Status

New-NexusOrientDbBackup -DataDir (Split-Path $Service.DataFolder) -ServiceName $Service.ServiceName -DestinationPath $MigrationFiles

try {
Push-Location $MigrationFiles
Write-Host "Migrating database from 'OrientDb' to 'H2'"
# We could adjust the memory values to work on more systems,
# but these are the recommended arguments from Sonatype.
$JavaArgs = @(
"-Xmx16G"
"-Xms16G"
"-XX:+UseG1GC"
"-XX:MaxDirectMemorySize=28672M"
"-jar"
$MigratorDownload.FileFullPath
JPRuskin marked this conversation as resolved.
Show resolved Hide resolved
"--migration_type=h2"
"--yes"
)
& $JavaPath @JavaArgs

if ($LASTEXITCODE -ne 0) {
throw "Migration of the database failed."
}

if ($PSCmdlet.ShouldProcess("$MigrationFiles\nexus.mv.db", "Moving migrated database")) {
Copy-Item -Path $MigrationFiles\nexus.mv.db -Destination (Join-Path $Service.DataFolder "db")
}
$NexusConfigFile = Join-Path $Service.DataFolder "etc\nexus.properties"
if ((Get-NexusConfiguration -Path $NexusConfigFile).'nexus.datastore.enabled' -ne 'true' -and $PSCmdlet.ShouldProcess($NexusConfigFile, 'Updating Datastore Configuration')) {
(Get-Content $NexusConfigFile) | Where-Object {$_ -notmatch '^\W*nexus\.datastore\.enabled='} | Set-Content $NexusConfigFile
Add-Content -Path $NexusConfigFile -Value "nexus.datastore.enabled=true"
}

if ($ServiceState -eq 'Running') {
try {
Write-Host "Restarting '$($Service.ServiceName)'"
Restart-Service $Service.ServiceName
# The post-migration launch can take significantly longer than normal
Wait-NexusAvailability -Hostname $Hostname -Config $NexusConfigFile -Timeout 15 -ErrorAction Stop
} catch {
Write-Error -Message (@(
"The Nexus service '$($Service.ServiceName)' was restarted, but did not recover."
"Check the logs at '$(Join-Path $Service.DataFolder "log")'"
) -join "`n")
}
}
} finally {
Pop-Location
Remove-Item $MigrationFiles -Recurse
}
} else {
Write-Warning "'$($Service.DataFolder)' was not migrated"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<#
.Synopsis
Repairs a broken upgrade of Sonatype Nexus Repository OSS

.Example
.\Repair-Nexus371FailedUpgrade.ps1
# Repairs the Nexus install, ending with a migrated database and version 3.71.0.6

.Example
.\Repair-Nexus371FailedUpgrade.ps1 -Rollback
# Repairs the Nexus install, ending with an unmodified database and version 3.70.1.2
#>
[CmdletBinding(DefaultParameterSetName="Upgrade")]
param(
# If selected, rolls the install back to 3.70.x instead of upgrading.
[Parameter(ParameterSetName="Repair")]
[Alias("Repair")]
[switch]$Rollback,

# Temporary Path for extracting files
[string]$ExtractPath = (Join-Path $env:Temp "nexus")
)
$ProgressPreference = "SilentlyContinue"
$ErrorActionPreference = "Stop"

Import-Module $PSScriptRoot\nexus-helpers.ps1 -Verbose:$false

# Test if Nexus JRE matches
$JavaPath = @(
Join-Path $env:ProgramData "\nexus\jre\bin\java.exe"
Convert-Path $env:JAVA_HOME\bin\java.exe
Convert-Path $env:ProgramFiles\*\jre-*\bin\java.exe
) | Where-Object {
$_ -and
(Test-Path $_) -and
(([version](Get-ItemProperty -Path $_).VersionInfo.ProductVersion).Major -in 8, 11)
} | Select-Object -First 1

# Download Java if it's missing, via the old version of Nexus Repository
if (-not $JavaPath -and -not ($JavaPath = Convert-Path "$ExtractPath\nexus-3.70.1-02\jre\bin\java.exe" -ErrorAction SilentlyContinue)) {
Invoke-WebRequest -Uri https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.70.1-02-win64.zip -OutFile "$env:Temp\nexus-3.70.1-02.zip"
Expand-Archive -Path "$env:Temp\nexus-3.70.1-02.zip" -DestinationPath $ExtractPath
$JavaPath = Convert-Path "$ExtractPath\nexus-3.70.1-02\jre\bin\java.exe"
Remove-Item "$env:Temp\nexus-3.70.1-02.zip"
}

$BackupLocation = "$PSScriptRoot\$(New-Guid)"
Backup-NexusSSL -BackupLocation $BackupLocation

# Get the "installed" and package version of Nexus
$NexusVersion = Get-NexusVersion
$null = [System.Reflection.Assembly]::LoadFrom("$env:ChocolateyInstall\choco.exe")
$LatestPackageVersion = [Chocolatey.NugetVersionExtensions]::ToNormalizedStringChecked(
"$($NexusVersion -replace '-','.')"
)

if ((Get-Service nexus).Status -ne 'running') {
if ($PSCmdlet.ParameterSetName -eq 'Upgrade') {
& $PSScriptRoot\ConvertFrom-NexusOrientDb.ps1 -JavaPath $JavaPath -Force
}

# The combined installation of old and new Nexus Java versions and supports
# causes the install to become un-startable. We'll replace it.
Remove-Item $env:ProgramData\nexus -Recurse

switch ($PSCmdlet.ParameterSetName) {
"Repair" {
Copy-Item -Path "$ExtractPath\nexus-3.70.1-02\" -Destination "$env:ProgramData\nexus" -Recurse
}
"Upgrade" {
# Download the matching version of Nexus
Invoke-WebRequest -Uri https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-$($NexusVersion)-win64.zip -OutFile "$env:Temp\nexus-$($NexusVersion)-win64.zip"
Expand-Archive -Path "$env:Temp\nexus-$($NexusVersion)-win64.zip" -DestinationPath $ExtractPath -Force
Copy-Item -Path "$ExtractPath\nexus-$NexusVersion\" -Destination "$env:ProgramData\nexus" -Recurse
Remove-Item "$env:Temp\nexus-$($NexusVersion)-win64.zip"

# Ensure the package is in a good state, from CCR as we know the local repository isn't running.
choco upgrade nexus-repository --version $LatestPackageVersion --confirm --no-progress --source https://community.chocolatey.org/api/v2/ --skip-powershell
}
}
} else {
Write-Warning "The service is already running. You don't need to repair."
}

try {
Restore-NexusSSL -BackupLocation $BackupLocation
} finally {
Remove-Item $BackupLocation -Recurse
}

Restart-Service nexus
27 changes: 27 additions & 0 deletions automatic/nexus-repository-migrator/tools/chocolateyInstall.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
$ErrorActionPreference = 'Stop'
$toolsDir = Split-Path $MyInvocation.MyCommand.Definition
$PackageParameters = Get-PackageParameters

$MigratorDownload = @{
PackageName = $env:ChocolateyPackageName
Url = 'https://download.sonatype.com/nexus/nxrm3-migrator/nexus-db-migrator-3.70.2-01.jar'
FileFullPath = Join-Path $toolsDir "nexus-db-migrator.jar"
Checksum = '69aebd05589a730af54d7b2cacba7d7bb5ea1f13dccd5e0d7eec002837068df0'
ChecksumType = 'SHA256'
}
Get-ChocolateyWebFile @MigratorDownload

$PowerShellScript = @{
packageName = $env:ChocolateyPackageName
PsFileFullPath = Join-Path $toolsDir "ConvertFrom-NexusOrientDb.ps1"
}
Install-ChocolateyPowershellCommand @PowerShellScript

if ($PackageParameters.Migrate) {
$ConvertArguments = @{}
if ($PackageParameters.FQDN) {
$ConvertArguments.Hostname = $PackageParameters.FQDN
}
& $toolsDir\ConvertFrom-NexusOrientDb.ps1 @ConvertArguments -ErrorAction Stop
Write-Host "You may now uninstall this package with 'choco uninstall $($env:ChocolateyPackageName) --confirm'."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
$ErrorActionPreference = 'Stop'
$toolsDir = Split-Path $MyInvocation.MyCommand.Definition

Uninstall-BinFile -Name "ConvertFrom-NexusOrientDb" -Path $toolsDir\ConvertFrom-NexusOrientDb.ps1
39 changes: 39 additions & 0 deletions automatic/nexus-repository-migrator/update.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Import-Module Chocolatey-AU

function global:au_GetLatest {
$R = Invoke-WebRequest -Uri https://help.sonatype.com/en/orientdb-downloads.html -UseBasicParsing
$MigratorUrl = $R.Links.href | Where-Object {
$_ -like 'https://download.sonatype.com/nexus/nxrm3-migrator/nexus-db-migrator-3.70.*.jar'
}

if ($MigratorUrl.Count -ne 1) {
throw "Found $($MigratorUrl.Count) URLs that look like the migrator:`n $($MigratorUrl -join "`n ")"
}

if ($MigratorUrl -match "/nexus-db-migrator-(?<Version>3\.70\.\d+-\d+)\.jar$") {
$NexusMigratorVersion = $Matches.Version
}

$null = [System.Reflection.Assembly]::LoadFrom("$env:ChocolateyInstall\choco.exe")
$LatestPackageVersion = [Chocolatey.NugetVersionExtensions]::ToNormalizedStringChecked(
"$($NexusMigratorVersion -replace '-','.')"
)

@{
NexusVersion = $NexusMigratorVersion
Version = $LatestPackageVersion
URL = $MigratorUrl
SHA256 = (Invoke-RestMethod "$MigratorUrl.sha256" -UseBasicParsing).Trim()
}
}

function global:au_SearchReplace {
@{
".\tools\chocolateyInstall.ps1" = @{
"(^\s*url\s*=\s*)('.*')" = "`$1'$($Latest.URL)'"
"(^\s*checksum\s*=\s*)('.*')" = "`$1'$($Latest.SHA256)'"
}
}
}

update -ChecksumFor none
16 changes: 12 additions & 4 deletions automatic/nexus-repository/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,25 @@ Nexus product does not have a built-in web gallery for components.

This package supports the following parameters:

* `/Fqdn` - The fqdn that matches the subject you are using for your Nexus instance SSL certificate.
* `/Port` - Specify what port Nexus should listen on. Defaults to `8081`.
* `/BackupSslConfig` - Ensures that the ssl configuration survives an upgrade.
* `/BackupLocation` - Species the path to backup ssl configuration to during upgrade. Defaults to `~/NexusSSLBackup`.
* `/Fqdn` - The fully-qualified domain name that matches the subject you are using for your Nexus instance SSL certificate.
* `/Port` - Specify what port Nexus should listen on. Defaults to `8081`, or whatever was previously configured.
* `/BackupSslConfig` - Ensures that the SSL configuration survives an upgrade, if it's otherwise undetected.
* `/BackupLocation` - Specifies the path to backup the SSL configuration to during upgrade. Defaults to `~/NexusSSLBackup`.

You can pass parameters as follows:

`choco install nexus-repository --parameters="/Fqdn='nexus.example.com' /Port=4443 /BackupSslConfig /BackupLocation='X:\Backup\NexusSSL'"`

## Notes

- **ATTENTION BREAKING CHANGE FOR UPGRADES FROM VERSIONS BEFORE 3.71.0.6**
Nexus has upgraded the bundled version of Java, and sunset the OrientDb database type.
This means that you will need to migrate your database from OrientDb, if you are using it.
See [here](https://help.sonatype.com/en/orient-3-70-java-8-or-11.html) for further details,
or check out the nexus-repository-migrator package.
Versions after this will also overwrite rather than merge the program directory, i.e. `$env:ProgramFiles/nexus`,
and back-up HTTPS configuration and the keystore from there if it is configured.

- **ATTENTION BREAKING CHANGE FOR UPGRADES FROM VERSIONS BEFORE 3.3.2.02**
Nexus no longer provided a setup.exe for installing Nexus Repository 3.x on Windows.
If you previously installed this with a package that used a setup.exe, you must manually uninstall it first (use choco uninstall nexus-repository if you used Chocolatey to install it). Once you are on 3.3.2.02 or later, upgrades will work smoothly.
Loading