Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement - Make execute["extract #{local_archive}"] idempotent by checking all content extracted and not single file #35

Open
poliva83 opened this issue Jul 20, 2015 · 2 comments

Comments

@poliva83
Copy link

Current logic uses execute resource's create attribute to decide if execute["extract #{local_archive}"] should be run. I'd rather add logic before resource that checks all content already exists in target_dir location. Then check that value through a guard to decide if execute["extract #{local_archive}"] can be skipped or not.

@gmiranda23
Copy link

I agree that this would be a good enhancement. Thinking through how this would be implemented, my thought is that we'd likely need to untar the TOC per archive we're dealing with on every Chef run. For small files, that's probably okay. For very large archives, that seems like a pretty computationally expensive operation on every run. Do you have some thoughts on how to accomplish this goal efficiently?

@poliva83
Copy link
Author

I am not sure if execute's create attribute actually checks the checksum of the file or if it just checks existence. If you only care about existence of archive content you could use tar -t flag to get the information of content and use it to confirm if all content already exists.

Below is how I implemented the logic currently:

  dest = ::File.join([Dir.home(some_user), 'some_dir', 'some_archive.tar']),

  dirname = ::File.dirname(dest)
  ext = ::File.extname(dest)
  ruby_block "Extract #{dest} if archive and content missing" do
    block do
      check = true
      `tar -tvf #{dest}`.split("\n").each do |content|
        check &= ::File.exist?(::File.join([dirname, content.split()[5]]))
      end

      f = Chef::Resource::TarExtract.new(dest, run_context)
      f.compress_char '' if ext.eql? '.tar'
      f.target_dir dirname
      f.only_if { !check }
      f.run_action :extract_local
    end
    action :run
    only_if { ext.eql? '.tar' or ext.eql? '.tgz' }
  end

** EDITED ** - removed piping through awk since you can do same thing through split()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants