Update Zammad fails with DB:migrate

Infos:

Good day, we are running an extremly old version of Zammad (2.5), because we had some issues updating, we never continued to other versions.
With a new server in our hands we wanted to move everything and upgrade to the (near) latest versions of all software.

i’ve started building Zammad 2.5 on the 22.04 machine (its still in testing phase), and it runs, the basic functions work. Because the upgrade notes suggest a Major version step-by-step upgrade. We’ve folled all steps, from 2.5 to 3.0, from 3.0 to 4.1.1, and now from 4.1.1 to 5.x.x.
note: Ubuntu 22.04 comes with an other openssl version, all rvm builds are done with openssl1.1.1n via: rvm install ruby-2.x.x --with-openssl-dir=/opt/openssl

i’ve managed to succesfully update to zammad 4.1.1, with ruby 2.6.8 and elasticsearch 6.5.4.

When i want to upgrade zammad from 4.1.1 to 5.x.x (tried 5.0.0 / 5.0.2 / 5.1.1) i’m not able to get past the ‘rake db:migrate’ command.

i’ve take notice that Ubuntu22.04 is not yet on the supported platforms list, but since it runs 2.5 → 4.1.1 i couldn’t realy see why this error is related to that. (correct me if i’m wrong).

  • Used Zammad version: 5.x.x
  • Used Zammad installation type: Source (MySQL)
  • Operating system: Ubuntu Server 22.04 LTS
  • Browser + version: Edge v101

Expected behavior:

  • DB:Migrate should succesfully finish after the update

Actual behavior:

$ rake db:migrate --trace
** Invoke db:migrate (first_time)
** Invoke db:load_config (first_time)
** Invoke environment (first_time)
** Execute environment
nil versions are discouraged and will be deprecated in Rubygems 4
** Execute db:load_config
** Execute db:migrate
rake aborted!
ActiveRecord::DuplicateMigrationNameError:

Multiple migrations have the name SettingAddInternalArticleCheck.

/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/migration.rb:1334:in 'validate'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/migration.rb:1204:in 'initialize'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/migration.rb:1061:in 'new'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/migration.rb:1061:in 'up'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/migration.rb:1036:in 'migrate'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/tasks/database_tasks.rb:238:in 'migrate'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/railties/databases.rake:86:in 'block (3 levels) in <main>'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/railties/databases.rake:84:in 'each'
/usr/share/rvm/gems/ruby-2.7.4/gems/activerecord-6.0.4.1/lib/active_record/railties/databases.rake:84:in 'block (2 levels) in <main>'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/task.rb:281:in 'block in execute'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/task.rb:281:in 'each'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/task.rb:281:in 'execute'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/task.rb:219:in 'block in invoke_with_call_chain'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/task.rb:199:in 'synchronize'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/task.rb:199:in 'invoke_with_call_chain'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/task.rb:188:in 'invoke'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:160:in 'invoke_task'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:116:in 'block (2 levels) in top_level'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:116:in 'each'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:116:in 'block in top_level'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:125:in 'run_with_threads'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:110:in 'top_level'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:83:in 'block in run'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:186:in 'standard_exception_handling'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/lib/rake/application.rb:80:in 'run'
/usr/share/rvm/gems/ruby-2.7.4/gems/rake-13.0.6/exe/rake:27:in '<top (required)>'
/usr/share/rvm/gems/ruby-2.7.4/bin/rake:23:in 'load'
/usr/share/rvm/gems/ruby-2.7.4/bin/rake:23:in '<main>'
/usr/share/rvm/gems/ruby-2.7.4/bin/ruby_executable_hooks:22:in 'eval'
/usr/share/rvm/gems/ruby-2.7.4/bin/ruby_executable_hooks:22:in '<main>'
Tasks: TOP => db:migrate

Steps to reproduce the behavior:

Because i’ve updated multiple versions i’ve used this routine

$ systemctl stop zammad
$ cp -r zammad zammad-4.1.1
$ su zammad
$ cd /opt/zammad
$ rails r "Cache.clear"
$ exit
$ apt install nodejs
$ echo "rvm --default use 2.7.4" >> /opt/zammad/.bashrc
$ cd /opt
$ wget https://ftp.zammad.com/zammad-5.0.2.tar.gz
$ tar -xzf zammad-5.0.2.tar.gz --strip-components 1 -C zammad
$ chown -R zammad:zammad zammad
$ su zammad
$ cd /opt/zammad
$ rvm install ruby-2.7.4 --with-openssl-dir=/opt/openssl ## Success
$  gem install bundler ## Success
$ bundle install --without test development postgres ## Success
$ rake db:migrate --trace ## Error```

Update on ticket:

investigating the database itself, changed every table and colum to utf8_general_ci.
Still got the error.

did an ‘search’ on the function called in the error, found that there where 2 migration files with nearly identical names.
After removing one of the files (oldest ) the DB:migrate seems to work correctly.

Details:

zammad@web01:~/db/migrate$ grep "SettingAddInternalArticleCheck" *
202104070000001_setting_add_internal_article_check.rb:class SettingAddInternalArticleCheck < ActiveRecord::Migration[5.2]
20210407000001_setting_add_internal_article_check.rb:class SettingAddInternalArticleCheck < ActiveRecord::Migration[5.2]
zammad@web01:~/db/migrate$ ls -alh *setting_add_internal_article_check*
-rw-r--r-- 1 zammad zammad  653 May  9 09:05 202104070000001_setting_add_internal_article_check.rb
-rw-r--r-- 1 zammad zammad 1.1K Oct 28  2021 20210407000001_setting_add_internal_article_check.rb
zammad@web01:~/db/migrate$ mv 20210407000001_setting_add_internal_article_check.rb /opt
mv: cannot move '20210407000001_setting_add_internal_article_check.rb' to '/opt/202104070000001_setting_add_internal_article_check.rb': Permission denied
zammad@web01:~/db/migrate$ exit
exit
root@web01:/opt/zammad$ mv db/migrate/20210407000001_setting_add_internal_article_check.rb /opt/
root@web01:/opt/zammad$ su zammad
Using /usr/share/rvm/gems/ruby-2.7.4
zammad@web01:~$ rake db:migrate --trace
** Invoke db:migrate (first_time)
** Invoke db:load_config (first_time)
** Invoke environment (first_time)
** Execute environment
nil versions are discouraged and will be deprecated in Rubygems 4
** Execute db:load_config
** Execute db:migrate
== 20191017122807 AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId: migrating
-- foreign_key_exists?(:active_storage_attachments, {:column=>:blob_id})
   -> 0.0025s
-- table_exists?(:active_storage_blobs)
   -> 0.0014s
== 20191017122807 AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId: migrated (0.0041s)

== 20210128131507 InitCoreWorkflow: migrating =================================
-- create_table(:core_workflows, {})
   -> 0.0432s
-- add_index(:core_workflows, [:name], {:unique=>true})
   -> 0.0225s
-- add_foreign_key(:core_workflows, :users, {:column=>:created_by_id})
   -> 0.0611s
-- add_foreign_key(:core_workflows, :users, {:column=>:updated_by_id})
   -> 0.0635s
== 20210128131507 InitCoreWorkflow: migrated (0.7389s) ========================

== 20210407000001 SettingAddInternalArticleCheck: migrating ===================
== 20210407000001 SettingAddInternalArticleCheck: migrated (0.0060s) ==========

== 20210701131549 Issue3579NewScheduler: migrating ============================
== 20210701131549 Issue3579NewScheduler: migrated (0.0412s) ===================

== 20210712101116 InclusiveWording: migrating =================================
-- rename_column(:chats, :whitelisted_websites, :allowed_websites)
   -> 0.0360s
== 20210712101116 InclusiveWording: migrated (0.0378s) ========================

== 20210728103633 MoveAuthBackendsToDatabase: migrating =======================
== 20210728103633 MoveAuthBackendsToDatabase: migrated (0.0755s) ==============

== 20210729183242 SetUserSourceLdapFromExternalSync: migrating ================
== 20210729183242 SetUserSourceLdapFromExternalSync: migrated (0.0244s) =======

== 20210731132202 SettingUpdatePasswordMaxLoginFailed: migrating ==============
== 20210731132202 SettingUpdatePasswordMaxLoginFailed: migrated (0.0152s) =====

== 20210812000001 JiraConfig: migrating =======================================
== 20210812000001 JiraConfig: migrated (0.0257s) ==============================

== 20210816125040 RenameNotificationSender: migrating =========================
== 20210816125040 RenameNotificationSender: migrated (0.0175s) ================

== 20210823112140 Issue2455FollowUpAssignment: migrating ======================
== 20210823112140 Issue2455FollowUpAssignment: migrated (0.0148s) =============

== 20210906153600 Issue257TicketSecondaryAction: migrating ====================
== 20210906153600 Issue257TicketSecondaryAction: migrated (0.0155s) ===========

== 20210909093800 Issue3168TokenSetting: migrating ============================
== 20210909093800 Issue3168TokenSetting: migrated (0.0115s) ===================

== 20210910112200 Issue3732AddCoreWorkflowPermission: migrating ===============
== 20210910112200 Issue3732AddCoreWorkflowPermission: migrated (0.0056s) ======

== 20210921112300 Issue3751MissingWorkflowScreens: migrating ==================
== 20210921112300 Issue3751MissingWorkflowScreens: migrated (0.0631s) =========

== 20210922090000 Issue3759CacheClear: migrating ==============================
== 20210922090000 Issue3759CacheClear: migrated (0.0069s) =====================

== 20210923075329 RemoveOtrsDiffWorkerSchedulerEntry: migrating ===============
== 20210923075329 RemoveOtrsDiffWorkerSchedulerEntry: migrated (0.0135s) ======

== 20210923172256 Issue2619KbHeaderLinkColor: migrating =======================
-- add_column(:knowledge_bases, :color_header_link, :string, {:limit=>25, :null=>false, :default=>"hsl(206,8%,50%)"})
   -> 0.0554s
-- change_column_default(:knowledge_bases, :color_header_link, nil)
   -> 0.0218s
== 20210923172256 Issue2619KbHeaderLinkColor: migrated (0.0795s) ==============

== 20210929161701 ReloadAfterCoreWorkflow: migrating ==========================
== 20210929161701 ReloadAfterCoreWorkflow: migrated (0.0198s) =================

== 20211004111501 ReloadAfterCoreWorkflowAgain: migrating =====================
== 20211004111501 ReloadAfterCoreWorkflowAgain: migrated (0.0112s) ============

== 20211005110047 Issue3787FixJob: migrating ==================================
== 20211005110047 Issue3787FixJob: migrated (0.0046s) =========================

== 20211020131134 Issue3810CustomDateAttributeNoDefault: migrating ============
== 20211020131134 Issue3810CustomDateAttributeNoDefault: migrated (0.0142s) ===

== 20211028072158 MaintenanceRemoveActiveLdapSessions: migrating ==============
== 20211028072158 MaintenanceRemoveActiveLdapSessions: migrated (0.0012s) =====

== 202104070000001 SettingAddInternalArticleCheck: migrating ==================
== 202104070000001 SettingAddInternalArticleCheck: migrated (0.0021s) =========

** Invoke db:_dump (first_time)
** Execute db:_dump