KBEC-00513 - How to resolve applications with duplicate names before upgrading from a version prior to v10.9

3 minute readKnowledge base

Issue

CloudBees v10.9 includes a fix for an issue that caused duplicate applications for applications created in the UI when using MariaDB, MySQL, and Postgres databases.

Before upgrading to CloudBees v10.9 or later from a version prior to v10.9, ensure that your current installation does not contain applications with duplicate names in the same project.

Resolution

The following steps allow you to find duplicate applications and optionally delete them.

The script below allows you to identify applications with duplicate names in your installation.

  1. Log in using ectool.

  2. Run ec-perl path/to/find-duplicate-apps.pl.

    use warnings; use strict; use Encode; use Data::Dumper; use ElectricCommander; $| = 1; my $ec = new ElectricCommander(); $ec->abortOnError(0); my $xpath = $ec->findObjects("application", { select => [ {propertyName => "applicationId"}, {propertyName => "applicationName"}, {propertyName => "projectName"}, {propertyName => "modifyTime"}], maxIds => "10000" }); my $nodeset = $xpath->find("//response/object/application"); my %apps; foreach my $node ($nodeset->get_nodelist) { my $projectName = $xpath->findvalue('projectName', $node)->value(); my $applicationName = $xpath->findvalue('applicationName', $node)->value(); my $key = lc($projectName) . "==" . lc($applicationName); if (exists($apps{$key})) { my @list = @{$apps{$key}}; push(@list, $node); $apps{$key} = \@list; } else { my @list = (); push(@list, $node); $apps{$key} = \@list; } } my %duplicateApps; while (my ($key, $node) = each %apps) { # find dupes in the app map my @list = @{$apps{$key}}; my $count = scalar @list; if ($count > 1) { #print "Duplicate app found $key = $count\n\n"; $duplicateApps{$key} = \@list; } } if (keys %duplicateApps == 0) { print "No duplicate applications found with same name and project\n"; } else { print "ResolveAction,ApplicationId,ProjectName,ApplicationName,UpdatedOn\n"; while (my ($key, $node) = each %duplicateApps) { my @list = @{$duplicateApps{$key}}; foreach my $node (@list) { my $projectName = $xpath->findvalue('projectName', $node)->value(); my $applicationName = $xpath->findvalue('applicationName', $node)->value(); my $applicationId = $xpath->findvalue('applicationId', $node)->value(); my $modifyTime = $xpath->findvalue('modifyTime', $node)->value(); print "<KEEP|DELETE>,${applicationId},${projectName},${applicationName},${modifyTime}\n"; } } } exit(0);

    The script generates the list of applications with duplicates found in the system.

    Sample output when there are duplicates:

    ResolveAction,ApplicationId,ProjectName,ApplicationName,UpdatedOn <KEEP|DELETE>,0305be80-4533-11ed-b131-42010a1eb05e,ProjectOne,App1,2022-10-06T04:54:51.457Z <KEEP|DELETE>,357ed090-78bf-11e8-a120-005056bb6bca,ProjectOne,app1,2018-06-25T21:32:06.608Z <KEEP|DELETE>,3a6d2e30-0e26-11e8-96d7-005056bb1fd4,ProjectTwo,App2,2019-02-15T11:33:10.453Z <KEEP|DELETE>,e7fffc94-df67-11ea-8039-005056bb04e9,ProjectTwo,app2,2020-08-16T02:26:35.453Z
  3. If duplicate applications are found, rerun the script redirecting the output to a file for use in the subsequent steps.

    ec-perl path/to/find-duplicate-apps.pl > path/to/dupe-apps.csv
  4. Edit path/to/dupe-apps.csv, replacing <KEEP|DELETE> with either KEEP to retain the application record or DELETE to delete it. The script below processes duplicate applications in path/to/dupe-apps.csv.

    use warnings; use strict; use Encode; use Data::Dumper; use ElectricCommander; use Switch; $| = 1; my $ec = new ElectricCommander(); $ec->abortOnError(0); @ARGV == 1 or die "Usage: resolve-duplicate-apps.pl input-file\n"; my $filename = $ARGV[0]; # open the file (or die trying) open(FILE, $filename) or die "Could not read from $filename."; my $count = 1; while (<FILE>) { # skip first line which is expected to be the header. if ($count > 1) { my $row = $_; #split on separator my @columns = split(',', $row); my $resolution = $columns[0]; my $applicationId = $columns[1]; my $projectName = $columns[2]; my $applicationName = $columns[3]; switch ($resolution){ case("DELETE") { print "Deleting application '$applicationName' in project '$projectName'\n"; $ec->deleteObjects("application", { filter => [{propertyName => "applicationId", operator => "equals", operand1 => "$applicationId"}]}); } case("KEEP") { } # nothing to do here else { print "Invalid resolve action on line $count. Must be KEEP or DELETE. Skipping row.\n"} } } $count++; } exit(0);
  5. Run the following to resolve duplicates.

    ec-perl path/to/resolve-duplicate-apps.pl path/to/dupe-apps.csv.
    The CloudBees Analytics server continues to maintain past application deployment history for deleted applications.