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.
-
Log in using ectool.
-
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
-
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
-
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 inpath/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);
-
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.