Carrierwave上传命中Errno::EEXIST-文件存在错误



已经在两台机器上安装了rails3.2.18应用程序:用于测试目的的Ubuntu 14.04和osx 10.6。

提交一个文件上传到OS X盒子上(这些文件故意很大),带有carrierwave返回Errno::EEXIST in [...] controller指定:

File exists - /Users/user/app/releases/20141018152115/public/uploads

此错误不会在Ubuntu安装中发生。public/uploads之所以存在,是因为它需要成为shared/public/uploads的符号链接以满足持久性需求。capistrano3部署命令

set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}

设置符号链接。为了更好地衡量,我在两台机器上依次运行部署,以隔离任何应用程序问题。

因此,这再次成为OSX的问题。一种假设是,给定的阶段文件在某种程度上被错误地配置为OSX,尽管适当地指定了具有管理权限的(唯一)用户:

set :deploy_to, '/Users/osxuser/app'
set :use_sudo, false
set :deploy_user, 'osxuser'

另一个假设与从Capistrano2迁移到Capistrano3有关,因为此osX服务器在升级之前没有此类问题。

如何消除"文件存在"错误?

更新

/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:244:in `mkdir'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:244:in `fu_mkdir'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:221:in `block (2 levels) in mkdir_p'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:219:in `reverse_each'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:219:in `block in mkdir_p'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:205:in `each'
/Users/osxuser/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/fileutils.rb:205:in `mkdir_p'
carrierwave (0.9.0) lib/carrierwave/sanitized_file.rb:290:in `mkdir!'
carrierwave (0.9.0) lib/carrierwave/sanitized_file.rb:209:in `copy_to'
carrierwave (0.9.0) lib/carrierwave/uploader/cache.rb:131:in `block in cache!'
carrierwave (0.9.0) lib/carrierwave/uploader/callbacks.rb:17:in `with_callbacks'
carrierwave (0.9.0) lib/carrierwave/uploader/cache.rb:122:in `cache!'
carrierwave (0.9.0) lib/carrierwave/mount.rb:327:in `cache'
carrierwave (0.9.0) lib/carrierwave/mount.rb:179:in `production_file='
carrierwave (0.9.0) lib/carrierwave/orm/activerecord.rb:38:in `production_file='
activerecord (3.2.18) lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes'
activerecord (3.2.18) lib/active_record/attribute_assignment.rb:78:in `each'
activerecord (3.2.18) lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
activerecord (3.2.18) lib/active_record/persistence.rb:216:in `block in update_attributes'
activerecord (3.2.18) lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'
activerecord (3.2.18) lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
activerecord (3.2.18) lib/active_record/transactions.rb:208:in `transaction'
activerecord (3.2.18) lib/active_record/transactions.rb:311:in `with_transaction_returning_status'
activerecord (3.2.18) lib/active_record/persistence.rb:215:in `update_attributes'
app/controllers/bozzadocuments_controller.rb:62:in `block in update'

堆栈跟踪似乎想要mkdir carrierwave (0.9.0) lib/carrierwave/sanitized_file.rb:290:in mkdir!

载波上传器指定如下

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{model.quote.cart_id}_#{model.quote.cart.created_at}_/#{model.quote_id}/#{model.id}"
  end

当创建OS-X"别名"而不是符号链接时,这是一个陷阱。

(没有在实际的宝石中,也没有任何特定的版本——我今天在rails 5.0.0.1、ruby 3.2.1和carrierwave 0.11.2中也经历了同样的情况。)

事实证明,我意外地使用OS X Finder创建了一个别名,而不是符号链接(从技术上讲,这不是符号链接)。当carrierwave尝试创建文件夹结构时,FileUtils.mkir_p在尝试(重新)创建(现有)别名作为目录时引发错误。

rm ./app/releases/20141018152115/public/uploads ln -s ./app/shared/public/uploads ./app/releases/$timestamp/public/uploads

应该做到这一点。

[EDIT:澄清实际根本原因不在ruby、rails或使用中的gems]

最新更新