Redmine DMSFプラグイン1.5.2〜2.4.4で発生する不具合を修正しました


概要

  • Redmine DMSFプラグインの特定のバージョンで発生していた不具合を修正しました
  • Redmine バージョン 3.4.0以上を使用していて Remine DMSFプラグイン バージョン 1.5.2〜2.4.4を使用している場合に発生します
  • 私の方で 当該の不具合を修正するPull Request を作成し受理されましたので、Redmine DMSF バージョン 2.4.5 以上では事象が発生しないようになっています
  • 本記事は 不具合報告したissue の内容に記載している情報とほぼ同様のものとなりますが、改めて不具合の内容について周知させていただきます

Redmine DMSFプラグインについて

Redmine DMSFプラグインRedmine で高機能な文書管理を行うプラグインです。
プロジェクト内でファイルをアップロードしてメンバーと共有する用途に向いています。
ファイル内容検索やバージョン管理、ファイル変更メール通知やWebDAV対応といった機能があります。

不具合の内容

Redmineのチケットへの添付を行っていたファイルと同じファイルをDMSFプラグイン(文書管理)からアップロードすると、チケット側で添付していたファイルが閲覧できなくなってしまう。

不具合の原因についての解説

※ここから先はRedmineの内部構造に踏み込む結構難解な解説となってしまうことをご容赦ください・・・。

1. そもそもRedmine DMSFプラグインがどのようにファイルアップロードを実装しているのか

Redmine DMSFプラグインは Redmineの添付ファイル( Attachement モデル)の機能をそのまま呼び出してファイルアップロードを実装しています。
以下の箇所ではファイルアップロード時にRedmineの Attachement#save を呼び出して実装していることが確認できます。

Redmine標準の添付ファイル機能を利用して保存しているので、いったんRedmineの標準的なアップロード先のディレクトリ(例: "#{RAILS_ROOT}/files/〜")に一時保存されます。
そして、DMSFプラグインではその一時保存されたファイルをDMSFプラグイン専用の保存先ディレクトリにファイル移動しています。

2. Redmine 3.4.0からの新機能「ファイルアップロード時のファイルの再利用」

Redmine 3.4.0から、ファイルアップロード時にファイルを再利用してディスク領域を節約する機能が追加されました。1
この新機能により、同一ファイルをRedmineに複数回アップロードしても、Redmineを稼働しているサーバのディスクにはファイルが1つしか保存されないようになりました。

この新機能は Redmineの Attachment モデルを改修することで実装されています。
https://github.com/redmine/redmine/blob/4.1.1/app/models/attachment.rb#L438

Attachment#reuse_existing_file_if_possible というファイルを再利用する処理が after_commit コールバックごとに呼び出されるようになりました。
この処理は古い同じファイル内容の添付ファイルを削除して、古い添付ファイル情報のファイルパスをすべて新しいものに書き換えるという実装になっています。

3. 不具合発生の流れ

Redmine DMSFが以前よりRedmineの Attachement モデルを利用してファイルアップロードを実装していましたが、Redmine 3.4.0で実装された新機能により、ファイルの再利用が自動で行われるようになってしまっていました。

上記をふまえて改めて不具合発生の流れを記載します。

  • Redmine DMSFプラグインが Redmine の Attachment#save によるアップロードされたファイルの保存を実施
  • Redmine側で「ファイルアップロード時のファイルの再利用」処理が実施され、アップロードされたファイルと同じファイルがRedmine内の添付ファイルに存在する場合、古い添付ファイルの実体が削除されて、新しいファイル(Redmine DMSFの一時保存ファイル)への参照に置換される
  • Redmine DMSFプラグイン側の処理でアップロードされた一時保存ファイルが、所定のディレクトリにファイル移動される
  • Redmineのチケットに添付していたファイル(の参照先のパス)が既に移動が行われたファイルのものとなっているため、Redmineのチケットのファイルを表示することができなくなってしまう

解決方法

Redmine DMSFプラグインがRemine 3.4.0からのファイル再利用の新機能に対する対応ができていなかったため、Redmine DMSFプラグインのファイルアップロードではこの新機能を利用しないようにする Pull Request を作成しました。
先日リリースされた バージョン2.4.5 ではPull Requestが取り込まれているため改修されています。

まとめ

  • Redmine DMSFプラグインの特定バージョンで発生する不具合について周知・説明しました
  • 本不具合について原因究明およびPull Request作成を実施しました

  1. Redmine 3.4 新機能紹介 が参考になります。