berkshelf / ridley

A reliable Chef API client with a clean syntax
Other
231 stars 85 forks source link

Digester breaks when trying to checksum non-files #367

Open 0cjs opened 7 years ago

0cjs commented 7 years ago

I set up a Vagrant test environment along the lines of my vagrant-demo that sets up the Vagrant instance with a serial console attached to a Unix domain socket .com1 in the same directory, along the lines of:

Vagrant.configure('2') { |c|
    c.vm.box = 'centos/7'
    com1_sock = File.join(File.dirname(__FILE__), '.com1')
    c.vm.provider("virtualbox") { |v|
        v.customize ['modifyvm', :id,
            '--uart1', '0x3f8', '4', '--uartmode1', 'server', com1_sock, ]
        v.gui = false
    }

knife solo cook vagrant fails as it tries to install the Berkshelf cookbooks:

Installing Berkshelf cookbooks to '/home/cjs/.berkshelf/knife-solo/cfd00f2cbdcc629007b0b56809e99f882a7d55ba'...
/home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/digester.rb:43:in `initialize': No such device or address @ rb_sysopen - /home/cjs/co/omise/sysadmin/chef-japan/.com1 (Errno::ENXIO)
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/digester.rb:43:in `open'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/digester.rb:43:in `checksum_file'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/digester.rb:33:in `generate_md5_checksum_for_file'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/digester.rb:16:in `md5_checksum_for_file'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:16:in `checksum'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:160:in `file_metadata'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:273:in `block (2 levels) in load_root'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:269:in `each'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:269:in `block in load_root'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:268:in `tap'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:268:in `load_root'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:264:in `load_files'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:93:in `initialize'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:47:in `new'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/ridley-5.1.0/lib/ridley/chef/cookbook.rb:47:in `from_path'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/locations/path.rb:21:in `cached_cookbook'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/dependency.rb:126:in `cached_cookbook'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/lockfile.rb:435:in `block in reduce!'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/lockfile.rb:416:in `each'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/lockfile.rb:416:in `reduce!'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/installer.rb:32:in `run'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/berksfile.rb:422:in `install'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/berksfile.rb:631:in `block in vendor'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/2.2.0/tmpdir.rb:88:in `mktmpdir'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/berkshelf-5.1.0/lib/berkshelf/berksfile.rb:629:in `vendor'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/knife-solo-0.6.0/lib/knife-solo/berkshelf.rb:30:in `install!'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/knife-solo-0.6.0/lib/knife-solo/cookbook_manager.rb:91:in `install'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/knife-solo-0.6.0/lib/chef/knife/solo_cook.rb:217:in `berkshelf_install'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/knife-solo-0.6.0/lib/chef/knife/solo_cook.rb:93:in `block in run'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/knife-solo-0.6.0/lib/chef/knife/solo_cook.rb:212:in `time'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/knife-solo-0.6.0/lib/chef/knife/solo_cook.rb:79:in `run'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/chef-12.10.24/lib/chef/knife.rb:421:in `block in run_with_pretty_exceptions'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/chef-12.10.24/lib/chef/local_mode.rb:44:in `with_server_connectivity'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/chef-12.10.24/lib/chef/knife.rb:420:in `run_with_pretty_exceptions'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/chef-12.10.24/lib/chef/knife.rb:219:in `run'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/chef-12.10.24/lib/chef/application/knife.rb:148:in `run'
    from /home/cjs/.rbenv/versions/2.2.5/lib/ruby/gems/2.2.0/gems/chef-12.10.24/bin/knife:25:in `<top (required)>'
    from /home/cjs/.rbenv/versions/2.2.5/bin/knife:22:in `load'
    from /home/cjs/.rbenv/versions/2.2.5/bin/knife:22:in `<main>'

The failing bit of code is:

def checksum_file(file, digest)
  File.open(file, 'rb') do |f|
    ...

Ruby's File.open cannot be used on sockets:

$ ls -l com1
srwxrwxr-x. 1 cjs cjs 0 Feb 16 13:03 com1
$ file com1
com1: socket
$ ruby -e 'File.open("com1")'
-e:1:in `initialize': No such device or address @ rb_sysopen - com1 (Errno::ENXIO)
    from -e:1:in `open'
    from -e:1:in `<main>'
$ 

I am not at all familiar with Ridley, but my guess is that the real problem lies in the load_root function in cookbook.rb:

  def load_root
    [].tap do |files|
      Dir.glob(path.join('*'), File::FNM_DOTMATCH).each do |file|
        next if File.directory?(file)
        next if ignored?(file)
        @files << file
        @manifest[:root_files] << file_metadata(:root_files, file)
      end
    end
  end

The test to see if it should add files to the manifest ignores directories, but as well as adding regular files it looks like it adds sockets, devices, and any other non-file items to the manifest. I believe the next if File.directory?(file) should probably be next unless File.file?(file).