Skip to content

Commit

Permalink
Merge pull request #6 from chef/i5pranay93/INFWS-94-berks-corrupt-arc…
Browse files Browse the repository at this point in the history
…hive

Berks package corrupt archive fixed using relative path
  • Loading branch information
vkarve-chef committed Jun 1, 2022
2 parents 57707c2 + 6f83719 commit 2af86be
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
17 changes: 17 additions & 0 deletions features/commands/package.feature
Expand Up @@ -15,3 +15,20 @@ Feature: berks package
"""
Cookbook(s) packaged to
"""
And the archive "my-cookbooks.tar.gz" should contain:
"""
cookbooks
cookbooks/fake
cookbooks/fake/attributes
cookbooks/fake/attributes/default.rb
cookbooks/fake/files
cookbooks/fake/files/default
cookbooks/fake/files/default/file.h
cookbooks/fake/metadata.json
cookbooks/fake/metadata.rb
cookbooks/fake/recipes
cookbooks/fake/recipes/default.rb
cookbooks/fake/templates
cookbooks/fake/templates/default
cookbooks/fake/templates/default/template.erb
"""
7 changes: 7 additions & 0 deletions features/step_definitions/utility_steps.rb
Expand Up @@ -2,6 +2,13 @@
skip
end

Then("the archive {string} should contain:") do |path, expected_contents|
actual_contents = Zlib::GzipReader.open(expand_path(path)) do |gz|
Archive::Tar::Minitar::Input.each_entry(gz).map(&:full_name).join("\n")
end
expect(actual_contents).to eql(expected_contents)
end

Then /the output from \`(.+)\` should be the same as \`(.+)\`/ do |actual, expected|
run(actual)
actual_output = last_command_started.stdout
Expand Down
40 changes: 38 additions & 2 deletions lib/berkshelf/packager.rb
@@ -1,4 +1,5 @@
require "archive/tar/minitar"
require "find" unless defined?(Find)
require "zlib" unless defined?(Zlib)

module Berkshelf
Expand Down Expand Up @@ -40,8 +41,18 @@ def initialize(out_file)
# @return [String]
# path to the generated archive
def run(source)
tgz = Zlib::GzipWriter.new(File.open(out_file, "wb"))
Archive::Tar::Minitar.pack(Dir.glob("#{source}/*"), tgz)
begin
dest = Zlib::GzipWriter.open(out_file)
tar = RelativeTarWriter.new(dest, source)
Find.find(source) do |entry|
next if source == entry

Archive::Tar::Minitar.pack_file(entry, tar)
end
ensure
tar.close
dest.close
end

out_file
rescue SystemCallError => ex
Expand All @@ -67,5 +78,30 @@ def validate!

# @return [String]
attr_reader :filename

# A private decorator for Archive::Tar::Minitar::Writer that
# turns absolute paths into relative ones.
class RelativeTarWriter < SimpleDelegator # :nodoc:
def initialize(io, base_path)
@base_path = Pathname.new(base_path)
super(Archive::Tar::Minitar::Writer.new(io))
end

%w{add_file add_file_simple mkdir}.each do |method|
class_eval <<~RUBY
def #{method}(name, *opts, &block)
super(relative_path(name), *opts, &block)
end
RUBY
end

private

attr_reader :base_path

def relative_path(path)
Pathname.new(path).relative_path_from(base_path).to_s
end
end
end
end

0 comments on commit 2af86be

Please sign in to comment.