Vendor the external cookbooks
Knife-Zero doesn't include Berkshelf support, so vendoring everything in the repo is convenient again
This commit is contained in:
43
cookbooks/poise-archive/CHANGELOG.md
Normal file
43
cookbooks/poise-archive/CHANGELOG.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Poise-Archive Changelog
|
||||
|
||||
## v1.5.0
|
||||
|
||||
* Support for 7-Zip unpacking archives on drives other than the system root.
|
||||
* Chef 13 support.
|
||||
|
||||
## v1.4.0
|
||||
|
||||
* Added support for using 7-Zip on Windows.
|
||||
* Fixed handling of `.tar.xz` archives on RHEL and CentOS.
|
||||
|
||||
## v1.3.0
|
||||
|
||||
* Add support for unpacking directly from a URL.
|
||||
|
||||
## v1.2.1
|
||||
|
||||
* [#1](https://github.com/poise/poise-archive/issues/1) Restore file permissions
|
||||
for ZIP files.
|
||||
|
||||
## v1.2.0
|
||||
|
||||
* Add back a tar-binary provider called `GnuTar`, used by default on Linux.
|
||||
* Support for ZIP files via RubyZip.
|
||||
* Full Windows support, including with the `user` and `group` properties.
|
||||
|
||||
## v1.1.2
|
||||
|
||||
* Fix compat with older Ruby that doesn't include `Entry#symlink?`.
|
||||
|
||||
## v1.1.1
|
||||
|
||||
* Fix GNU tar longlink extension.
|
||||
|
||||
## v1.1.0
|
||||
|
||||
* Scrap the original tar implementation in favor of a 100% pure-Ruby solution.
|
||||
This should work on all platforms exactly the same. Hopefully.
|
||||
|
||||
## v1.0.0
|
||||
|
||||
* Initial release!
|
||||
103
cookbooks/poise-archive/README.md
Normal file
103
cookbooks/poise-archive/README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Poise-Archive Cookbook
|
||||
|
||||
[](https://travis-ci.org/poise/poise-archive)
|
||||
[](https://rubygems.org/gems/poise-archive)
|
||||
[](https://supermarket.chef.io/cookbooks/poise-archive)
|
||||
[](https://codecov.io/github/poise/poise-archive)
|
||||
[](https://gemnasium.com/poise/poise-archive)
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
A [Chef](https://www.chef.io/) cookbook to unpack file archives.
|
||||
|
||||
It supports `.tar`, `.tar.gz`, `.tar.bz2`, and `.zip` archive files.
|
||||
|
||||
## Quick Start
|
||||
|
||||
To download an unpack and archive:
|
||||
|
||||
```ruby
|
||||
poise_archive 'https://example.com/myapp.tgz' do
|
||||
destination '/opt/myapp'
|
||||
end
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
Chef 12.1 or newer is required.
|
||||
|
||||
## Platforms
|
||||
|
||||
This cookbook supports all platforms (including Windows) but some Unix platforms
|
||||
(Solaris, AIX) may see very slow tar file unpacking when using the pure-Ruby fallback
|
||||
implementation.
|
||||
|
||||
## Resources
|
||||
|
||||
### `poise_archive`
|
||||
|
||||
The `poise_archive` resource unpacks file archives.
|
||||
|
||||
```ruby
|
||||
poise_archive '/tmp/myapp-1.2.0.tar' do
|
||||
destination '/srv/myapp-1.2.0'
|
||||
end
|
||||
```
|
||||
|
||||
A URL can also be passed as the source path, optionally with extra properties to
|
||||
be merged with `source_properties`.
|
||||
|
||||
```ruby
|
||||
poise_archive 'http://example.com/myapp-1.2.0.zip' do
|
||||
destination '/srv/myapp-1.2.0'
|
||||
end
|
||||
|
||||
poise_archive ['http://example.com/myapp-1.2.0.zip', {headers: {'Authentication' => '...'}}] do
|
||||
destination '/srv/myapp-1.2.0'
|
||||
end
|
||||
```
|
||||
|
||||
#### Actions
|
||||
|
||||
* `:unpack` – Unpack the archive. *(default)*
|
||||
|
||||
#### Properties
|
||||
|
||||
* `path` – Path to the archive. If relative, it is taken as a file inside
|
||||
`Chef::Config[:file_cache_path]`. If a URL, it is downloaded to a cache file
|
||||
first. *(name attribute)*
|
||||
* `destination` – Path to unpack the archive to. If not specified, the path of
|
||||
the archive without the file extension is used. Required when unpacking from
|
||||
a URL. *(default: auto)*
|
||||
* `group` – Group to run the unpack as.
|
||||
* `keep_existing` – Keep existing files in the destination directory when
|
||||
unpacking. *(default: false)*
|
||||
* `source_properties` – Property key/value pairs to be applied to the
|
||||
`remote_file` file resource when downloading a URL. *(default: {retries: 5})*
|
||||
* `strip_components` – Number of intermediary directories to skip when
|
||||
unpacking. Works like GNU tar's `--strip-components`. *(default: 1)*
|
||||
* `user` – User to run the unpack as.
|
||||
|
||||
## Sponsors
|
||||
|
||||
Development sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/).
|
||||
|
||||
The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2016-2017, Noah Kantrowitz
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
BZip2 implementation is based on RBzip2. Copyright Sebastian Staudt, Brian Lopez.
|
||||
RBzip2 code used under the terms of the new BSD license.
|
||||
18
cookbooks/poise-archive/attributes/default.rb
Normal file
18
cookbooks/poise-archive/attributes/default.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright 2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
default['poise-archive']['seven_zip']['version'] = '16.04'
|
||||
default['poise-archive']['seven_zip']['url'] = 'http://www.7-zip.org/a/7z%{version_tag}%{arch_tag}.exe'
|
||||
21
cookbooks/poise-archive/files/halite_gem/poise_archive.rb
Normal file
21
cookbooks/poise-archive/files/halite_gem/poise_archive.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
autoload :Resources, 'poise_archive/resources'
|
||||
autoload :VERSION, 'poise_archive/version'
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/platform/provider_priority_map'
|
||||
|
||||
require 'poise_archive/archive_providers/gnu_tar'
|
||||
require 'poise_archive/archive_providers/seven_zip'
|
||||
require 'poise_archive/archive_providers/tar'
|
||||
require 'poise_archive/archive_providers/zip'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
# Providers for the poise_archive resource.
|
||||
#
|
||||
# @since 1.0.0
|
||||
module ArchiveProviders
|
||||
# Set up priority maps
|
||||
Chef::Platform::ProviderPriorityMap.instance.priority(:poise_archive, [
|
||||
PoiseArchive::ArchiveProviders::Zip,
|
||||
PoiseArchive::ArchiveProviders::GnuTar,
|
||||
PoiseArchive::ArchiveProviders::SevenZip,
|
||||
PoiseArchive::ArchiveProviders::Tar,
|
||||
])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,132 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'fileutils'
|
||||
|
||||
require 'chef/provider'
|
||||
require 'poise'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
module ArchiveProviders
|
||||
# The provider base class for `poise_archive`.
|
||||
#
|
||||
# @see PoiseArchive::Resources::PoiseArchive::Resource
|
||||
# @provides poise_archive
|
||||
class Base < Chef::Provider
|
||||
include Poise
|
||||
|
||||
# Set the file extension this provider will handle.
|
||||
#
|
||||
# @param match [RegExp] Regular expression to match against the archive
|
||||
# file name.
|
||||
# @return [void]
|
||||
# @example
|
||||
# class MyProvider < Base
|
||||
# provides_extension(/\.hqx$/)
|
||||
# end
|
||||
def self.provides_extension(match)
|
||||
provides(:poise_archive)
|
||||
@provides_extension = match
|
||||
end
|
||||
|
||||
# Override normal provider resolution to also check file extension if one
|
||||
# was specified in the provider.
|
||||
#
|
||||
# @api private
|
||||
def self.provides?(node, resource)
|
||||
super && (!@provides_extension || @provides_extension.match(resource.path))
|
||||
end
|
||||
|
||||
# `unpack` action for `poise_archive`.
|
||||
#
|
||||
# @return [void]
|
||||
def action_unpack
|
||||
if new_resource.is_url?
|
||||
download_resource = download_file
|
||||
# Check if the download resource updated, if not don't run the rest
|
||||
# of the unpack for idempotence. I could also check
|
||||
# new_resource.updated? but this seems more future proof.
|
||||
return if !download_resource.updated_by_last_action?
|
||||
end
|
||||
converge_by("unpack archive #{new_resource.path} to #{new_resource.destination}") do
|
||||
notifying_block do
|
||||
create_directory
|
||||
end
|
||||
empty_directory
|
||||
unpack_archive
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Download the source file to a cache path.
|
||||
#
|
||||
# @return [Chef::Resource]
|
||||
def download_file
|
||||
# resource_state used for closure breaking on the notifying block.
|
||||
resource_state = []
|
||||
notifying_block do
|
||||
# TODO handle cookbook:// for cookbook_file "downloads".
|
||||
resource_state << remote_file(new_resource.absolute_path) do
|
||||
source new_resource.path
|
||||
retries 5 # As a default, could be overridden by source_properties.
|
||||
new_resource.merged_source_properties.each do |key, value|
|
||||
send(key, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
# Return the download resource for state tracking.
|
||||
resource_state.first
|
||||
end
|
||||
|
||||
# Make sure the destination directory exists.
|
||||
#
|
||||
# @return [void]
|
||||
def create_directory
|
||||
directory new_resource.destination do
|
||||
group new_resource.group if new_resource.group
|
||||
owner new_resource.user if new_resource.user
|
||||
# There is explicitly no mode being set here. If a non-default mode
|
||||
# is needed, you should manage that outside of poise_archive.
|
||||
end
|
||||
end
|
||||
|
||||
# Remove all existing content from the destination so we can unpack the
|
||||
# new content.
|
||||
#
|
||||
# @return [void]
|
||||
def empty_directory
|
||||
# If you want to keep it, not my problem.
|
||||
return if new_resource.keep_existing
|
||||
dest = new_resource.destination
|
||||
Dir.entries(dest).each do |entry|
|
||||
next if entry == '.' || entry == '..'
|
||||
FileUtils.remove_entry_secure(::File.join(dest, entry))
|
||||
end
|
||||
end
|
||||
|
||||
# Run the provider-specific unpack behavior.
|
||||
#
|
||||
# @abstract
|
||||
# @return [void]
|
||||
def unpack_archive
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,88 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'fileutils'
|
||||
require 'tmpdir'
|
||||
|
||||
require 'poise_archive/archive_providers/base'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
module ArchiveProviders
|
||||
# The `gnu_tar` provider class for `poise_archive` to install from TAR
|
||||
# archives using GNU's tar executable.
|
||||
#
|
||||
# @see PoiseArchive::Resources::PoiseArchive::Resource
|
||||
# @provides poise_archive
|
||||
class GnuTar < Base
|
||||
provides_extension(/\.t(ar|gz|bz|xz)/)
|
||||
|
||||
# Only use this if we are on Linux. Everyone else gets the slow Ruby code.
|
||||
#
|
||||
# @api private
|
||||
def self.provides?(node, _resource)
|
||||
super && node['os'] == 'linux'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def unpack_archive
|
||||
notifying_block do
|
||||
install_prereqs
|
||||
end
|
||||
unpack_tar
|
||||
end
|
||||
|
||||
# Install any needed prereqs.
|
||||
#
|
||||
# @return [void]
|
||||
def install_prereqs
|
||||
utils = ['tar']
|
||||
utils << 'bzip2' if new_resource.absolute_path =~ /\.t?bz/
|
||||
if new_resource.absolute_path =~ /\.t?xz/
|
||||
xz_package = node.value_for_platform_family(
|
||||
debian: 'xz-utils',
|
||||
rhel: 'xz',
|
||||
)
|
||||
utils << xz_package if xz_package
|
||||
end
|
||||
# This is a resource.
|
||||
package utils
|
||||
end
|
||||
|
||||
# Unpack the archive and process `strip_components`.
|
||||
#
|
||||
# @return [void]
|
||||
def unpack_tar
|
||||
# Build the tar command.
|
||||
cmd = %w{tar}
|
||||
cmd << "--strip-components=#{new_resource.strip_components}" if new_resource.strip_components && new_resource.strip_components > 0
|
||||
cmd << if new_resource.absolute_path =~ /\.t?gz/
|
||||
'-xzvf'
|
||||
elsif new_resource.absolute_path =~ /\.t?bz/
|
||||
'-xjvf'
|
||||
elsif new_resource.absolute_path =~ /\.t?xz/
|
||||
'-xJvf'
|
||||
else
|
||||
'-xvf'
|
||||
end
|
||||
cmd << new_resource.absolute_path
|
||||
poise_shell_out!(cmd, cwd: new_resource.destination, group: new_resource.group, user: new_resource.user)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,183 @@
|
||||
#
|
||||
# Copyright 2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'fileutils'
|
||||
require 'tmpdir'
|
||||
|
||||
|
||||
require 'poise_archive/archive_providers/base'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
module ArchiveProviders
|
||||
# The `seven_zip` provider class for `poise_archive` to upack archives
|
||||
# using 7-Zip.
|
||||
#
|
||||
# @since 1.4.0
|
||||
# @see PoiseArchive::Resources::PoiseArchive::Resource
|
||||
# @provides poise_archive
|
||||
class SevenZip < Base
|
||||
provides_extension(/\.(t(ar|gz|bz|xz)|zip|7z)/)
|
||||
|
||||
# Only works on Windows, because use less silly things elsewhere.
|
||||
#
|
||||
# @api private
|
||||
def self.provides?(node, _resource)
|
||||
super && node['platform_family'] == 'windows'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def unpack_archive
|
||||
notifying_block do
|
||||
install_seven_zip
|
||||
end
|
||||
# Create a temp directory to unpack in to. Do I want to try and force
|
||||
# this to be on the same filesystem as the target?
|
||||
self.class.mktmpdir do |tmpdir|
|
||||
unpack_using_seven_zip(tmpdir)
|
||||
chown_files(tmpdir) if new_resource.user || new_resource.group
|
||||
move_files(tmpdir)
|
||||
end
|
||||
end
|
||||
|
||||
# Install 7-Zip to a cache folder.
|
||||
#
|
||||
# @api private
|
||||
# @return [void]
|
||||
def install_seven_zip
|
||||
url = seven_zip_url
|
||||
path = "#{Chef::Config[:file_cache_path]}/#{url.split(/\//).last}"
|
||||
|
||||
install = execute "#{windows_path(path)} /S /D=#{seven_zip_home}" do
|
||||
action :nothing
|
||||
end
|
||||
|
||||
remote_file path do
|
||||
source url
|
||||
notifies :run, install, :immediately
|
||||
end
|
||||
end
|
||||
|
||||
# Unpack the whole archive to a temp directory.
|
||||
#
|
||||
# @api private
|
||||
# @param tmpdir [String] Temp directory to unpack to.
|
||||
# @return [void]
|
||||
def unpack_using_seven_zip(tmpdir)
|
||||
if new_resource.absolute_path =~ /\.t(ar\.)?(gz|bz(2)?|xz)$/
|
||||
# 7-Zip doesn't know to unpack both levels of the archive on its own
|
||||
# so we need to handle this more explicitly.
|
||||
shell_out!("#{seven_zip_home}\\7z.exe x -so \"#{windows_path(new_resource.absolute_path)}\" | #{seven_zip_home}\\7z.exe x -si -ttar -o\"#{windows_path(tmpdir)}\"")
|
||||
else
|
||||
shell_out!("#{seven_zip_home}\\7z.exe x -o\"#{windows_path(tmpdir)}\" \"#{windows_path(new_resource.absolute_path)}\"")
|
||||
end
|
||||
end
|
||||
|
||||
# Fix file ownership if requested.
|
||||
#
|
||||
# @api private
|
||||
# @param tmpdir [String] Temp directory to change ownership in.
|
||||
# @return [void]
|
||||
def chown_files(tmpdir)
|
||||
notifying_block do
|
||||
Dir["#{tmpdir}/**/*"].each do |path|
|
||||
declare_resource(::File.directory?(path) ? :directory : :file, path) do
|
||||
owner new_resource.user if new_resource.user
|
||||
group new_resource.group if new_resource.group
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Manual implementation of --strip-components since 7-Zip doesn't support
|
||||
# it internally.
|
||||
#
|
||||
# @api private
|
||||
# @param tmpdir [String] Temp directory to move from.
|
||||
# @return [void]
|
||||
def move_files(tmpdir)
|
||||
entries_at_depth(tmpdir, new_resource.strip_components).each do |source|
|
||||
target = ::File.join(new_resource.destination, ::File.basename(source))
|
||||
FileUtils.mv(source, target, secure: true)
|
||||
end
|
||||
end
|
||||
|
||||
# Compute the URL to download the 7-Zip installer from.
|
||||
#
|
||||
# @api private
|
||||
# @return [String]
|
||||
def seven_zip_url
|
||||
node['poise-archive']['seven_zip']['url'] % {
|
||||
version: node['poise-archive']['seven_zip']['version'],
|
||||
version_tag: node['poise-archive']['seven_zip']['version'].gsub(/\./, ''),
|
||||
arch: node['kernel']['machine'],
|
||||
arch_tag: node['kernel']['machine'] == 'x86_64' ? '-x64' : '',
|
||||
}
|
||||
end
|
||||
|
||||
# Path to install 7-Zip in to.
|
||||
#
|
||||
# @api private
|
||||
# @return [String]
|
||||
def seven_zip_home
|
||||
"#{windows_path(Chef::Config[:file_cache_path])}\\seven_zip_#{node['poise-archive']['seven_zip']['version']}"
|
||||
end
|
||||
|
||||
# Flip the slashes in a path because 7z wants "normal" paths.
|
||||
#
|
||||
# @api private
|
||||
# @param path [String] Path to convert.
|
||||
# @return [String]
|
||||
def windows_path(path)
|
||||
path.gsub(/\//, '\\')
|
||||
end
|
||||
|
||||
# Find the absolute paths for entries under a path at a depth.
|
||||
#
|
||||
# @api private
|
||||
# @param path [String] Base path to search under.
|
||||
# @param depth [Integer] Number of intermediary directories to skip.
|
||||
# @return [Array<String>]
|
||||
def entries_at_depth(path, depth)
|
||||
entries = [path]
|
||||
current_depth = 0
|
||||
while current_depth <= depth
|
||||
entries.map! do |ent|
|
||||
if ::File.directory?(ent)
|
||||
Dir.entries(ent).select {|e| e != '.' && e != '..' }.map {|e| ::File.join(ent, e) }
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
entries.flatten!
|
||||
current_depth += 1
|
||||
end
|
||||
entries
|
||||
end
|
||||
|
||||
# Indirection so I can stub this for testing without breaking RSpec.
|
||||
#
|
||||
# @api private
|
||||
def self.mktmpdir(*args, &block)
|
||||
# :nocov:
|
||||
Dir.mktmpdir(*args, &block)
|
||||
# :nocov:
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,158 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'rubygems/package'
|
||||
require 'zlib'
|
||||
|
||||
require 'poise_archive/archive_providers/base'
|
||||
require 'poise_archive/bzip2'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
module ArchiveProviders
|
||||
# The `tar` provider class for `poise_archive` to install from tar archives.
|
||||
#
|
||||
# @see PoiseArchive::Resources::PoiseArchive::Resource
|
||||
# @provides poise_archive
|
||||
class Tar < Base
|
||||
provides_extension(/\.t(ar|gz|bz)/)
|
||||
|
||||
# Hack that GNU tar uses for paths over 100 bytes.
|
||||
#
|
||||
# @api private
|
||||
# @see #unpack_tar
|
||||
TAR_LONGLINK = '././@LongLink'
|
||||
|
||||
private
|
||||
|
||||
def unpack_archive
|
||||
unpack_tar
|
||||
chown_entries if new_resource.user || new_resource.group
|
||||
end
|
||||
|
||||
# Unpack the archive.
|
||||
#
|
||||
# @return [void]
|
||||
def unpack_tar
|
||||
@tar_entry_paths = []
|
||||
tar_each_with_longlink do |entry|
|
||||
entry_name = entry.full_name.split(/\//).drop(new_resource.strip_components).join('/')
|
||||
# If strip_components wiped out the name, don't process this entry.
|
||||
next if entry_name.empty?
|
||||
dest = ::File.join(new_resource.destination, entry_name)
|
||||
if entry.directory?
|
||||
Dir.mkdir(dest, entry.header.mode)
|
||||
@tar_entry_paths << [:directory, dest]
|
||||
elsif entry.file?
|
||||
::File.open(dest, 'wb', entry.header.mode) do |dest_f|
|
||||
while buf = entry.read(4096)
|
||||
dest_f.write(buf)
|
||||
end
|
||||
end
|
||||
@tar_entry_paths << [:file, dest]
|
||||
elsif entry.header.typeflag == '2' # symlink? is new in Ruby 2.0, apparently.
|
||||
::File.symlink(entry.header.linkname, dest)
|
||||
@tar_entry_paths << [:link, dest]
|
||||
else
|
||||
raise RuntimeError.new("Unknown tar entry type #{entry.header.typeflag.inspect} in #{new_resource.path}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def tar_each_with_longlink(&block)
|
||||
entry_name = nil
|
||||
tar_each do |entry|
|
||||
if entry.full_name == TAR_LONGLINK
|
||||
# Stash the longlink name so it will be used for the next entry.
|
||||
entry_name = entry.read.strip
|
||||
# And then skip forward because this isn't a real block.
|
||||
next
|
||||
end
|
||||
# For entries not preceded by a longlink block, use the normal name.
|
||||
entry_name ||= entry.full_name
|
||||
# Make the entry return the correct name.
|
||||
entry.define_singleton_method(:full_name) { entry_name }
|
||||
block.call(entry)
|
||||
# Reset entry_name for the next entry.
|
||||
entry_name = nil
|
||||
end
|
||||
end
|
||||
|
||||
# Sequence the opening, iteration, and closing.
|
||||
#
|
||||
# @param block [Proc] Block to process each tar entry.
|
||||
# @return [void]
|
||||
def tar_each(&block)
|
||||
# In case of extreme weirdness where this happens twice.
|
||||
close_file!
|
||||
open_file!
|
||||
@tar_reader.each(&block)
|
||||
ensure
|
||||
close_file!
|
||||
end
|
||||
|
||||
# Open a file handle of the correct flavor.
|
||||
#
|
||||
# @return [void]
|
||||
def open_file!
|
||||
@raw_file = ::File.open(new_resource.absolute_path, 'rb')
|
||||
@file = case new_resource.absolute_path
|
||||
when /\.tar$/
|
||||
nil # So it uses @raw_file instead.
|
||||
when /\.t?gz/
|
||||
Zlib::GzipReader.wrap(@raw_file)
|
||||
when /\.t?bz/
|
||||
# This can't take a block, hence the gross non-block forms for everything.
|
||||
PoiseArchive::Bzip2::Decompressor.new(@raw_file)
|
||||
else
|
||||
raise RuntimeError.new("Unknown or unsupported file extension for #{new_resource.path}")
|
||||
end
|
||||
@tar_reader = Gem::Package::TarReader.new(@file || @raw_file)
|
||||
end
|
||||
|
||||
# Close all the various file handles.
|
||||
#
|
||||
# @return [void]
|
||||
def close_file!
|
||||
if @tar_reader
|
||||
@tar_reader.close
|
||||
@tar_reader = nil
|
||||
end
|
||||
if @file
|
||||
@file.close
|
||||
@file = nil
|
||||
end
|
||||
if @raw_file
|
||||
@raw_file.close unless @raw_file.closed?
|
||||
@raw_file = nil
|
||||
end
|
||||
end
|
||||
|
||||
def chown_entries
|
||||
paths = @tar_entry_paths
|
||||
notifying_block do
|
||||
paths.each do |type, path|
|
||||
send(type, path) do
|
||||
group new_resource.group
|
||||
owner new_resource.user
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise_archive/archive_providers/base'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
module ArchiveProviders
|
||||
# The `zip` provider class for `poise_archive` to install from ZIP archives.
|
||||
#
|
||||
# @see PoiseArchive::Resources::PoiseArchive::Resource
|
||||
# @provides poise_archive
|
||||
class Zip < Base
|
||||
provides_extension(/\.zip$/)
|
||||
|
||||
private
|
||||
|
||||
def unpack_archive
|
||||
check_rubyzip
|
||||
unpack_zip
|
||||
chown_entries if new_resource.user || new_resource.group
|
||||
end
|
||||
|
||||
def check_rubyzip
|
||||
require 'zip'
|
||||
rescue LoadError
|
||||
notifying_block do
|
||||
install_rubyzip
|
||||
end
|
||||
require 'zip'
|
||||
end
|
||||
|
||||
def install_rubyzip
|
||||
chef_gem 'rubyzip'
|
||||
end
|
||||
|
||||
def unpack_zip
|
||||
@zip_entry_paths = []
|
||||
::Zip::File.open(new_resource.absolute_path) do |zip_file|
|
||||
zip_file.each do |entry|
|
||||
entry_name = entry.name.split(/\//).drop(new_resource.strip_components).join('/')
|
||||
# If strip_components wiped out the name, don't process this entry.
|
||||
next if entry_name.empty?
|
||||
entry_path = ::File.join(new_resource.destination, entry_name)
|
||||
# Ensure parent directories exist because some ZIP files don't
|
||||
# include those for some reason.
|
||||
ensure_directory(entry_path)
|
||||
entry.extract(entry_path)
|
||||
# Make sure we restore file permissions. RubyZip won't do this
|
||||
# unless we also turn on UID/GID restoration, which we don't want.
|
||||
# Mask filters out setuid and setgid bits because no.
|
||||
::File.chmod(entry.unix_perms & 01777, entry_path) if !node.platform_family?('windows') && entry.unix_perms
|
||||
@zip_entry_paths << [entry.directory? ? :directory : entry.file? ? :file : :link, entry_path]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Make sure all enclosing directories exist before writing a path.
|
||||
#
|
||||
# @param oath [String] Path to check.
|
||||
def ensure_directory(path)
|
||||
base = ::File.dirname(path)
|
||||
unless ::File.exist?(base)
|
||||
ensure_directory(base)
|
||||
Dir.mkdir(base)
|
||||
@zip_entry_paths << [:directory, base]
|
||||
end
|
||||
end
|
||||
|
||||
def chown_entries
|
||||
paths = @zip_entry_paths
|
||||
notifying_block do
|
||||
paths.each do |type, path|
|
||||
send(type, path) do
|
||||
group new_resource.group
|
||||
owner new_resource.user
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
# This code is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the new BSD License.
|
||||
#
|
||||
# Copyright (c) 2013, Sebastian Staudt
|
||||
|
||||
|
||||
module PoiseArchive::Bzip2
|
||||
|
||||
autoload :CRC, 'poise_archive/bzip2/crc'
|
||||
autoload :Constants, 'poise_archive/bzip2/constants'
|
||||
autoload :Decompressor, 'poise_archive/bzip2/decompressor'
|
||||
autoload :IO, 'poise_archive/bzip2/io'
|
||||
autoload :InputData, 'poise_archive/bzip2/input_data'
|
||||
autoload :OutputData, 'poise_archive/bzip2/output_data'
|
||||
|
||||
end
|
||||
25
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/LICENSE
Executable file
25
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/LICENSE
Executable file
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2011, Sebastian Staudt
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
83
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/constants.rb
Executable file
83
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/constants.rb
Executable file
@@ -0,0 +1,83 @@
|
||||
# This code is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the new BSD License.
|
||||
#
|
||||
# Copyright (c) 2011-2013, Sebastian Staudt
|
||||
|
||||
|
||||
module PoiseArchive::Bzip2::Constants
|
||||
|
||||
BASEBLOCKSIZE = 100000
|
||||
MAX_ALPHA_SIZE = 258
|
||||
MAX_CODE_LEN = 23
|
||||
RUNA = 0
|
||||
RUNB = 1
|
||||
N_GROUPS = 6
|
||||
G_SIZE = 50
|
||||
N_ITERS = 4
|
||||
MAX_SELECTORS = (2 + (900000 / G_SIZE))
|
||||
NUM_OVERSHOOT_BYTES = 20
|
||||
|
||||
EOF = 0
|
||||
START_BLOCK_STATE = 1
|
||||
RAND_PART_A_STATE = 2
|
||||
RAND_PART_B_STATE = 3
|
||||
RAND_PART_C_STATE = 4
|
||||
NO_RAND_PART_A_STATE = 5
|
||||
NO_RAND_PART_B_STATE = 6
|
||||
NO_RAND_PART_C_STATE = 7
|
||||
|
||||
RNUMS = [
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863,
|
||||
491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869,
|
||||
675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727,
|
||||
476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819,
|
||||
984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666,
|
||||
933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383,
|
||||
461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318,
|
||||
353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680,
|
||||
81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580,
|
||||
124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511,
|
||||
655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493,
|
||||
403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640,
|
||||
724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631,
|
||||
212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829,
|
||||
82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524,
|
||||
462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986,
|
||||
403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857,
|
||||
265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
]
|
||||
|
||||
MIN_BLOCK_SIZE = 1
|
||||
MAX_BLOCK_SIZE = 9
|
||||
SETMASK = (1 << 21)
|
||||
CLEARMASK = (~SETMASK)
|
||||
GREATER_ICOST = 15
|
||||
LESSER_ICOST = 0
|
||||
SMALL_THRESH = 20
|
||||
DEPTH_THRESH = 10
|
||||
WORK_FACTOR = 30
|
||||
QSORT_STACK_SIZE = 1000
|
||||
|
||||
INCS = [
|
||||
1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161,
|
||||
2391484
|
||||
]
|
||||
|
||||
end
|
||||
73
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/crc.rb
Executable file
73
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/crc.rb
Executable file
@@ -0,0 +1,73 @@
|
||||
# This code is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the new BSD License.
|
||||
#
|
||||
# Copyright (c) 2011-2013, Sebastian Staudt
|
||||
|
||||
|
||||
class PoiseArchive::Bzip2::CRC
|
||||
|
||||
CRC32_TABLE = [
|
||||
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
||||
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
|
||||
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
|
||||
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
|
||||
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
|
||||
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
||||
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
|
||||
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
||||
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
|
||||
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
|
||||
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
||||
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
|
||||
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
||||
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
|
||||
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
|
||||
0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
|
||||
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
|
||||
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
||||
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
|
||||
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
||||
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
|
||||
0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
|
||||
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
||||
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
|
||||
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
]
|
||||
|
||||
attr_accessor :global_crc
|
||||
|
||||
def initialize
|
||||
initialize_crc
|
||||
end
|
||||
|
||||
def initialize_crc
|
||||
@global_crc = 0xffffffff
|
||||
end
|
||||
|
||||
def final_crc
|
||||
@global_crc ^ 0xffffffff
|
||||
end
|
||||
|
||||
def update_crc(in_ch)
|
||||
@global_crc = ((@global_crc << 8) & 0xffffffff) ^ CRC32_TABLE[(@global_crc >> 24) ^ in_ch]
|
||||
end
|
||||
|
||||
end
|
||||
704
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/decompressor.rb
Executable file
704
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/decompressor.rb
Executable file
@@ -0,0 +1,704 @@
|
||||
# This code is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the new BSD License.
|
||||
#
|
||||
# Copyright (c) 2011-2013, Sebastian Staudt
|
||||
|
||||
|
||||
class PoiseArchive::Bzip2::Decompressor
|
||||
|
||||
include PoiseArchive::Bzip2::Constants
|
||||
|
||||
def initialize(io)
|
||||
@buff = 0
|
||||
@bytes_read = 0
|
||||
@computed_combined_crc = 0
|
||||
@crc = PoiseArchive::Bzip2::CRC.new
|
||||
@current_char = -1
|
||||
@io = io
|
||||
@live = 0
|
||||
@stored_combined_crc = 0
|
||||
@su_t_pos = 0
|
||||
init
|
||||
end
|
||||
|
||||
def count(read)
|
||||
@bytes_read += read if read != -1
|
||||
end
|
||||
|
||||
# ADDED METHODS
|
||||
def pos
|
||||
@bytes_read
|
||||
end
|
||||
|
||||
def eof?
|
||||
@current_state == EOF
|
||||
end
|
||||
# /ADDED METHODS
|
||||
|
||||
def read(length = nil)
|
||||
raise 'stream closed' if @io.nil?
|
||||
|
||||
if length == 1
|
||||
r = read0
|
||||
count (r < 0 ? -1 : 1)
|
||||
r
|
||||
else
|
||||
r = ''
|
||||
if length == nil
|
||||
while true do
|
||||
b = read0
|
||||
break if b < 0
|
||||
r << b.chr
|
||||
end
|
||||
count r.size # ADDED LINE
|
||||
elsif length > 0
|
||||
length.times do
|
||||
b = read0
|
||||
break if b < 0
|
||||
r << b.chr
|
||||
end
|
||||
count r.size
|
||||
end
|
||||
r
|
||||
end
|
||||
end
|
||||
|
||||
def read0
|
||||
ret_char = @current_char
|
||||
|
||||
if @current_state == RAND_PART_B_STATE
|
||||
setup_rand_part_b
|
||||
elsif @current_state == NO_RAND_PART_B_STATE
|
||||
setup_no_rand_part_b
|
||||
elsif @current_state == RAND_PART_C_STATE
|
||||
setup_rand_part_c
|
||||
elsif @current_state == NO_RAND_PART_C_STATE
|
||||
setup_no_rand_part_c
|
||||
elsif @current_state == EOF
|
||||
return -1
|
||||
else
|
||||
raise 'illegal state'
|
||||
end
|
||||
|
||||
ret_char
|
||||
end
|
||||
|
||||
def make_maps
|
||||
in_use = @data.in_use
|
||||
seq_to_unseq = @data.seq_to_unseq
|
||||
|
||||
n_in_use_shadow = 0
|
||||
|
||||
256.times do |i|
|
||||
if in_use[i]
|
||||
seq_to_unseq[n_in_use_shadow] = i
|
||||
n_in_use_shadow += 1
|
||||
end
|
||||
end
|
||||
|
||||
@n_in_use = n_in_use_shadow
|
||||
end
|
||||
|
||||
def init
|
||||
check_magic
|
||||
|
||||
block_size = @io.read(1).to_i
|
||||
raise 'Illegal block size.' if block_size < 1 || block_size > 9
|
||||
@block_size = block_size
|
||||
|
||||
init_block
|
||||
setup_block
|
||||
end
|
||||
|
||||
def check_magic
|
||||
raise 'Magic number does not match "BZh".' unless @io.read(3) == 'BZh'
|
||||
end
|
||||
|
||||
def init_block
|
||||
magic = [ubyte, ubyte, ubyte, ubyte, ubyte, ubyte]
|
||||
|
||||
if magic == [0x17, 0x72, 0x45, 0x38, 0x50, 0x90]
|
||||
complete
|
||||
elsif magic != [0x31, 0x41, 0x59, 0x26, 0x53, 0x59]
|
||||
@current_state = EOF
|
||||
|
||||
raise 'Bad block header.'
|
||||
else
|
||||
@stored_block_crc = int
|
||||
@block_randomised = bit
|
||||
|
||||
@data = PoiseArchive::Bzip2::InputData.new @block_size if @data.nil?
|
||||
|
||||
get_and_move_to_front_decode
|
||||
|
||||
@crc.initialize_crc
|
||||
@current_state = START_BLOCK_STATE
|
||||
end
|
||||
end
|
||||
|
||||
def end_block
|
||||
@computed_block_crc = @crc.final_crc
|
||||
|
||||
if @stored_block_crc != @computed_block_crc
|
||||
@computed_combined_crc = (@stored_combined_crc << 1) | (@stored_combined_crc >> 31)
|
||||
@computed_combined_crc ^= @stored_block_crc
|
||||
|
||||
raise 'BZip2 CRC error'
|
||||
end
|
||||
|
||||
@computed_combined_crc = (@computed_combined_crc << 1) | (@computed_combined_crc >> 31)
|
||||
@computed_combined_crc ^= @computed_block_crc
|
||||
end
|
||||
|
||||
def complete
|
||||
@stored_combined_crc = int
|
||||
@current_state = EOF
|
||||
@data = nil
|
||||
|
||||
raise 'BZip2 CRC error' if @stored_combined_crc != @computed_combined_crc
|
||||
end
|
||||
|
||||
def close
|
||||
if @io != $stdin
|
||||
@io = nil
|
||||
@data = nil
|
||||
end
|
||||
end
|
||||
|
||||
def r(n)
|
||||
live_shadow = @live
|
||||
buff_shadow = @buff
|
||||
|
||||
if live_shadow < n
|
||||
begin
|
||||
thech = @io.readbyte
|
||||
|
||||
raise 'unexpected end of stream' if thech < 0
|
||||
|
||||
buff_shadow = (buff_shadow << 8) | thech
|
||||
live_shadow += 8
|
||||
end while live_shadow < n
|
||||
|
||||
@buff = buff_shadow
|
||||
end
|
||||
|
||||
@live = live_shadow - n
|
||||
|
||||
(buff_shadow >> (live_shadow - n)) & ((1 << n) - 1)
|
||||
end
|
||||
|
||||
def bit
|
||||
r(1) != 0
|
||||
end
|
||||
|
||||
def ubyte
|
||||
r 8
|
||||
end
|
||||
|
||||
def int
|
||||
(((((r(8) << 8) | r(8)) << 8) | r(8)) << 8) | r(8)
|
||||
end
|
||||
|
||||
def create_decode_tables(limit, base, perm, length, min_len, max_len, alpha_size)
|
||||
pp = 0
|
||||
(min_len..max_len).each do |i|
|
||||
alpha_size.times do |j|
|
||||
if length[j] == i
|
||||
perm[pp] = j
|
||||
pp += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MAX_CODE_LEN.downto 1 do |i|
|
||||
base[i] = 0
|
||||
limit[i] = 0
|
||||
end
|
||||
|
||||
alpha_size.times do |i|
|
||||
base[length[i] + 1] += 1
|
||||
end
|
||||
|
||||
b = 0
|
||||
1.upto(MAX_CODE_LEN - 1) do |i|
|
||||
b += base[i]
|
||||
base[i] = b
|
||||
end
|
||||
|
||||
vec = 0
|
||||
min_len.upto(max_len) do |i|
|
||||
b = base[i]
|
||||
nb = base[i + 1]
|
||||
vec += nb - b
|
||||
b = nb
|
||||
limit[i] = vec - 1
|
||||
vec = vec << 1
|
||||
end
|
||||
|
||||
(min_len + 1).upto(max_len) do |i|
|
||||
base[i] = ((limit[i - 1] + 1) << 1) - base[i]
|
||||
end
|
||||
end
|
||||
|
||||
def receive_decoding_tables
|
||||
in_use = @data.in_use
|
||||
pos = @data.receive_decoding_tables_pos
|
||||
selector = @data.selector
|
||||
selector_mtf = @data.selector_mtf
|
||||
|
||||
in_use16 = 0
|
||||
|
||||
16.times do |i|
|
||||
in_use16 |= 1 << i if bit
|
||||
end
|
||||
|
||||
255.downto(0) do |i|
|
||||
in_use[i] = false
|
||||
end
|
||||
|
||||
16.times do |i|
|
||||
if (in_use16 & (1 << i)) != 0
|
||||
i16 = i << 4
|
||||
16.times do |j|
|
||||
in_use[i16 + j] = true if bit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
make_maps
|
||||
alpha_size = @n_in_use + 2
|
||||
|
||||
groups = r 3
|
||||
selectors = r 15
|
||||
|
||||
selectors.times do |i|
|
||||
j = 0
|
||||
while bit
|
||||
j += 1
|
||||
end
|
||||
selector_mtf[i] = j
|
||||
end
|
||||
|
||||
groups.downto(0) do |v|
|
||||
pos[v] = v
|
||||
end
|
||||
|
||||
selectors.times do |i|
|
||||
v = selector_mtf[i] & 0xff
|
||||
tmp = pos[v]
|
||||
|
||||
while v > 0 do
|
||||
pos[v] = pos[v -= 1]
|
||||
end
|
||||
|
||||
pos[0] = tmp
|
||||
selector[i] = tmp
|
||||
end
|
||||
|
||||
len = @data.temp_char_array_2d
|
||||
|
||||
groups.times do |t|
|
||||
curr = r 5
|
||||
len_t = len[t]
|
||||
alpha_size.times do |i|
|
||||
while bit
|
||||
curr += bit ? -1 : 1
|
||||
end
|
||||
len_t[i] = curr
|
||||
end
|
||||
@data.temp_char_array_2d[t] = len_t
|
||||
end
|
||||
|
||||
create_huffman_decoding_tables alpha_size, groups
|
||||
end
|
||||
|
||||
def create_huffman_decoding_tables(alpha_size, groups)
|
||||
len = @data.temp_char_array_2d
|
||||
min_lens = @data.min_lens
|
||||
limit = @data.limit
|
||||
base = @data.base
|
||||
perm = @data.perm
|
||||
|
||||
groups.times do |t|
|
||||
min_len = 32
|
||||
max_len = 0
|
||||
len_t = len[t]
|
||||
|
||||
(alpha_size - 1).downto 0 do |i|
|
||||
lent = len_t[i]
|
||||
max_len = lent if lent > max_len
|
||||
min_len = lent if lent < min_len
|
||||
end
|
||||
|
||||
create_decode_tables limit[t], base[t], perm[t], len[t], min_len, max_len, alpha_size
|
||||
min_lens[t] = min_len
|
||||
end
|
||||
end
|
||||
|
||||
def get_and_move_to_front_decode
|
||||
@orig_ptr = r 24
|
||||
receive_decoding_tables
|
||||
|
||||
ll8 = @data.ll8
|
||||
unzftab = @data.unzftab
|
||||
selector = @data.selector
|
||||
seq_to_unseq = @data.seq_to_unseq
|
||||
yy = @data.get_and_move_to_front_decode_yy
|
||||
min_lens = @data.min_lens
|
||||
limit = @data.limit
|
||||
base = @data.base
|
||||
perm = @data.perm
|
||||
limit_last = @block_size * BASEBLOCKSIZE
|
||||
|
||||
256.downto(0) do |i|
|
||||
yy[i] = i
|
||||
unzftab[i] = 0
|
||||
end
|
||||
|
||||
group_no = 0
|
||||
group_pos = G_SIZE - 1
|
||||
eob = @n_in_use + 1
|
||||
next_sym = get_and_move_to_front_decode0 0
|
||||
buff_shadow = @buff
|
||||
live_shadow = @live
|
||||
last_shadow = -1
|
||||
zt = selector[group_no] & 0xff
|
||||
base_zt = base[zt]
|
||||
limit_zt = limit[zt]
|
||||
perm_zt = perm[zt]
|
||||
min_lens_zt = min_lens[zt]
|
||||
|
||||
while next_sym != eob
|
||||
if (next_sym == RUNA) || (next_sym == RUNB)
|
||||
s = -1
|
||||
|
||||
n = 1
|
||||
while true do
|
||||
if next_sym == RUNA
|
||||
s += n
|
||||
elsif next_sym == RUNB
|
||||
s += n << 1
|
||||
else
|
||||
break
|
||||
end
|
||||
|
||||
if group_pos == 0
|
||||
group_pos = G_SIZE - 1
|
||||
group_no += 1
|
||||
zt = selector[group_no] & 0xff
|
||||
base_zt = base[zt]
|
||||
limit_zt = limit[zt]
|
||||
perm_zt = perm[zt]
|
||||
min_lens_zt = min_lens[zt]
|
||||
else
|
||||
group_pos -= 1
|
||||
end
|
||||
|
||||
zn = min_lens_zt
|
||||
|
||||
while live_shadow < zn
|
||||
thech = @io.readbyte
|
||||
|
||||
raise 'unexpected end of stream' if thech < 0
|
||||
|
||||
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
||||
live_shadow += 8
|
||||
end
|
||||
|
||||
zvec = ((buff_shadow >> (live_shadow - zn)) & 0xffffffff) & ((1 << zn) - 1)
|
||||
live_shadow -= zn
|
||||
|
||||
while zvec > limit_zt[zn]
|
||||
zn += 1
|
||||
|
||||
while live_shadow < 1
|
||||
thech = @io.readbyte
|
||||
|
||||
raise 'unexpected end of stream' if thech < 0
|
||||
|
||||
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
||||
live_shadow += 8
|
||||
end
|
||||
|
||||
live_shadow -= 1
|
||||
zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
|
||||
end
|
||||
|
||||
next_sym = perm_zt[zvec - base_zt[zn]]
|
||||
|
||||
n = n << 1
|
||||
end
|
||||
|
||||
ch = seq_to_unseq[yy[0]]
|
||||
unzftab[ch & 0xff] += s + 1
|
||||
|
||||
while s >= 0
|
||||
last_shadow += 1
|
||||
ll8[last_shadow] = ch
|
||||
s -= 1
|
||||
end
|
||||
|
||||
raise 'block overrun' if last_shadow >= limit_last
|
||||
else
|
||||
last_shadow += 1
|
||||
raise 'block overrun' if last_shadow >= limit_last
|
||||
|
||||
tmp = yy[next_sym - 1]
|
||||
unzftab[seq_to_unseq[tmp] & 0xff] += 1
|
||||
ll8[last_shadow] = seq_to_unseq[tmp]
|
||||
|
||||
yy[1, next_sym - 1] = yy[0, next_sym - 1]
|
||||
yy[0] = tmp
|
||||
|
||||
if group_pos == 0
|
||||
group_pos = G_SIZE - 1
|
||||
group_no += 1
|
||||
zt = selector[group_no] & 0xff
|
||||
base_zt = base[zt]
|
||||
limit_zt = limit[zt]
|
||||
perm_zt = perm[zt]
|
||||
min_lens_zt = min_lens[zt]
|
||||
else
|
||||
group_pos -= 1
|
||||
end
|
||||
|
||||
zn = min_lens_zt
|
||||
|
||||
while live_shadow < zn
|
||||
thech = @io.readbyte
|
||||
|
||||
raise 'unexpected end of stream' if thech < 0
|
||||
|
||||
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
||||
live_shadow += 8
|
||||
end
|
||||
zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1)
|
||||
live_shadow -= zn
|
||||
|
||||
while zvec > limit_zt[zn]
|
||||
zn += 1
|
||||
while live_shadow < 1
|
||||
thech = @io.readbyte
|
||||
|
||||
raise 'unexpected end of stream' if thech < 0
|
||||
|
||||
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
||||
live_shadow += 8
|
||||
end
|
||||
live_shadow -= 1
|
||||
zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
|
||||
end
|
||||
|
||||
next_sym = perm_zt[zvec - base_zt[zn]]
|
||||
end
|
||||
end
|
||||
|
||||
@last = last_shadow
|
||||
@live = live_shadow
|
||||
@buff = buff_shadow
|
||||
end
|
||||
|
||||
def get_and_move_to_front_decode0(group_no)
|
||||
zt = @data.selector[group_no] & 0xff
|
||||
limit_zt = @data.limit[zt]
|
||||
zn = @data.min_lens[zt]
|
||||
zvec = r zn
|
||||
live_shadow = @live
|
||||
buff_shadow = @buff
|
||||
|
||||
while zvec > limit_zt[zn]
|
||||
zn += 1
|
||||
|
||||
while live_shadow < 1
|
||||
thech = @io.readbyte
|
||||
|
||||
raise 'unexpected end of stream' if thech < 0
|
||||
|
||||
buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech
|
||||
live_shadow += 8
|
||||
end
|
||||
|
||||
live_shadow -=1
|
||||
zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1)
|
||||
end
|
||||
|
||||
@live = live_shadow
|
||||
@buff = buff_shadow
|
||||
|
||||
@data.perm[zt][zvec - @data.base[zt][zn]]
|
||||
end
|
||||
|
||||
def setup_block
|
||||
return if @data.nil?
|
||||
|
||||
cftab = @data.cftab
|
||||
tt = @data.init_tt @last + 1
|
||||
ll8 = @data.ll8
|
||||
cftab[0] = 0
|
||||
cftab[1, 256] = @data.unzftab[0, 256]
|
||||
|
||||
c = cftab[0]
|
||||
1.upto(256) do |i|
|
||||
c += cftab[i]
|
||||
cftab[i] = c
|
||||
end
|
||||
|
||||
last_shadow = @last
|
||||
(last_shadow + 1).times do |i|
|
||||
cftab_i = ll8[i] & 0xff
|
||||
tt[cftab[cftab_i]] = i
|
||||
cftab[cftab_i] += 1
|
||||
end
|
||||
|
||||
raise 'stream corrupted' if @orig_ptr < 0 || @orig_ptr >= tt.size
|
||||
|
||||
@su_t_pos = tt[@orig_ptr]
|
||||
@su_count = 0
|
||||
@su_i2 = 0
|
||||
@su_ch2 = 256
|
||||
|
||||
if @block_randomised
|
||||
@su_r_n_to_go = 0
|
||||
@su_r_t_pos = 0
|
||||
|
||||
setup_rand_part_a
|
||||
else
|
||||
setup_no_rand_part_a
|
||||
end
|
||||
end
|
||||
|
||||
def setup_rand_part_a
|
||||
if @su_i2 <= @last
|
||||
@su_ch_prev = @su_ch2
|
||||
su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
|
||||
@su_t_pos = @data.tt[@su_t_pos]
|
||||
|
||||
if @su_r_n_to_go == 0
|
||||
@su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
|
||||
@su_r_t_pos += 1
|
||||
@su_r_t_pos = 0 if @su_r_t_pos == 512
|
||||
else
|
||||
@su_r_n_to_go -= 1
|
||||
end
|
||||
|
||||
@su_ch2 = su_ch2_shadow ^= (@su_r_n_to_go == 1) ? 1 : 0
|
||||
@su_i2 += 1
|
||||
@current_char = su_ch2_shadow
|
||||
@current_state = RAND_PART_B_STATE
|
||||
@crc.update_crc su_ch2_shadow
|
||||
else
|
||||
end_block
|
||||
init_block
|
||||
setup_block
|
||||
end
|
||||
end
|
||||
|
||||
def setup_no_rand_part_a
|
||||
if @su_i2 <= @last
|
||||
@su_ch_prev = @su_ch2
|
||||
su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff
|
||||
@su_ch2 = su_ch2_shadow
|
||||
@su_t_pos = @data.tt[@su_t_pos]
|
||||
@su_i2 += 1
|
||||
@current_char = su_ch2_shadow
|
||||
@current_state = NO_RAND_PART_B_STATE
|
||||
@crc.update_crc su_ch2_shadow
|
||||
else
|
||||
@current_state = NO_RAND_PART_A_STATE
|
||||
end_block
|
||||
init_block
|
||||
setup_block
|
||||
end
|
||||
end
|
||||
|
||||
def setup_rand_part_b
|
||||
if @su_ch2 != @su_ch_prev
|
||||
@current_state = RAND_PART_A_STATE
|
||||
@su_count = 1
|
||||
setup_rand_part_a
|
||||
else
|
||||
@su_count += 1
|
||||
if @su_count >= 4
|
||||
@su_z = @data.ll8[@su_t_pos] & 0xff
|
||||
@su_t_pos = @data.tt[@su_t_pos]
|
||||
|
||||
if @su_r_n_to_go == 0
|
||||
@su_r_n_to_go = RNUMS[@su_r_t_pos] - 1
|
||||
@su_r_t_pos += 1
|
||||
@su_r_t_pos = 0 if @su_r_t_pos == 512
|
||||
else
|
||||
@su_r_n_to_go -= 1
|
||||
end
|
||||
|
||||
@su_j2 = 0
|
||||
@current_state = RAND_PART_C_STATE
|
||||
@su_z ^= 1 if @su_r_n_to_go == 1
|
||||
setup_rand_part_c
|
||||
else
|
||||
@current_state = RAND_PART_A_STATE
|
||||
setup_rand_part_a
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup_rand_part_c
|
||||
if @su_j2 < @su_z
|
||||
@current_char = @su_ch2
|
||||
@crc.update_crc @su_ch2
|
||||
@su_j2 += 1
|
||||
else
|
||||
@current_state = RAND_PART_A_STATE
|
||||
@su_i2 += 1
|
||||
@su_count = 0
|
||||
setup_rand_part_a
|
||||
end
|
||||
end
|
||||
|
||||
def setup_no_rand_part_b
|
||||
if @su_ch2 != @su_ch_prev
|
||||
@su_count = 1
|
||||
setup_no_rand_part_a
|
||||
else
|
||||
@su_count += 1
|
||||
if @su_count >= 4
|
||||
@su_z = @data.ll8[@su_t_pos] & 0xff
|
||||
@su_t_pos = @data.tt[@su_t_pos]
|
||||
@su_j2 = 0
|
||||
setup_no_rand_part_c
|
||||
else
|
||||
setup_no_rand_part_a
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup_no_rand_part_c
|
||||
if @su_j2 < @su_z
|
||||
su_ch2_shadow = @su_ch2
|
||||
@current_char = su_ch2_shadow
|
||||
@crc.update_crc su_ch2_shadow
|
||||
@su_j2 += 1
|
||||
@current_state = NO_RAND_PART_C_STATE
|
||||
else
|
||||
@su_i2 += 1
|
||||
@su_count = 0
|
||||
setup_no_rand_part_a
|
||||
end
|
||||
end
|
||||
|
||||
def size
|
||||
if @io.is_a? StringIO
|
||||
@io.size
|
||||
elsif @io.is_a? File
|
||||
@io.stat.size
|
||||
end
|
||||
end
|
||||
|
||||
def uncompressed
|
||||
@last + 1
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>"
|
||||
end
|
||||
|
||||
end
|
||||
43
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/input_data.rb
Executable file
43
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/input_data.rb
Executable file
@@ -0,0 +1,43 @@
|
||||
# This code is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the new BSD License.
|
||||
#
|
||||
# Copyright (c) 2011-2013, Sebastian Staudt
|
||||
|
||||
|
||||
class PoiseArchive::Bzip2::InputData
|
||||
|
||||
include PoiseArchive::Bzip2::Constants
|
||||
|
||||
attr_reader :base, :cftab, :get_and_move_to_front_decode_yy, :in_use,
|
||||
:limit, :ll8, :min_lens, :perm, :receive_decoding_tables_pos,
|
||||
:selector, :selector_mtf, :seq_to_unseq, :temp_char_array_2d,
|
||||
:unzftab, :tt
|
||||
|
||||
def initialize(block_size)
|
||||
@in_use = Array.new 256, false
|
||||
|
||||
@seq_to_unseq = Array.new 256, 0
|
||||
@selector = Array.new MAX_SELECTORS, 0
|
||||
@selector_mtf = Array.new MAX_SELECTORS, 0
|
||||
|
||||
@unzftab = Array.new 256, 0
|
||||
|
||||
@base = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) }
|
||||
@limit = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) }
|
||||
@perm = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) }
|
||||
@min_lens = Array.new N_GROUPS, 0
|
||||
|
||||
@cftab = Array.new 257, 0
|
||||
@get_and_move_to_front_decode_yy = Array.new 256
|
||||
@temp_char_array_2d = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) }
|
||||
@receive_decoding_tables_pos = Array.new N_GROUPS, 0
|
||||
|
||||
@ll8 = Array.new block_size * BASEBLOCKSIZE
|
||||
end
|
||||
|
||||
def init_tt(size)
|
||||
@tt = Array.new(size) if @tt.nil? || @tt.size < size
|
||||
@tt
|
||||
end
|
||||
|
||||
end
|
||||
57
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/output_data.rb
Executable file
57
cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/output_data.rb
Executable file
@@ -0,0 +1,57 @@
|
||||
# This code is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the new BSD License.
|
||||
#
|
||||
# Copyright (c) 2011-2013, Sebastian Staudt
|
||||
|
||||
|
||||
class PoiseArchive::Bzip2::OutputData
|
||||
|
||||
include PoiseArchive::Bzip2::Constants
|
||||
|
||||
attr_reader :block, :ftab, :fmap, :generate_mtf_values_yy, :heap, :in_use,
|
||||
:main_sort_big_done, :main_sort_copy, :main_sort_running_order,
|
||||
:mtf_freq, :parent, :quadrant, :selector, :selector_mtf,
|
||||
:send_mtf_values_code, :send_mtf_values_cost,
|
||||
:send_mtf_values_fave, :send_mtf_values_len,
|
||||
:send_mtf_values_rfreq, :send_mtf_values2_pos,
|
||||
:send_mtf_values4_in_use_16, :sfmap, :stack_dd, :stack_hh,
|
||||
:stack_ll, :unseq_to_seq, :weight
|
||||
|
||||
def initialize(block_size)
|
||||
n = block_size * BASEBLOCKSIZE
|
||||
@block = Array.new n + 1 + NUM_OVERSHOOT_BYTES, 0
|
||||
@fmap = Array.new n, 0
|
||||
@selector = Array.new MAX_SELECTORS
|
||||
@selector_mtf = Array.new MAX_SELECTORS
|
||||
@sfmap = Array.new 2 * n
|
||||
@quadrant = @sfmap
|
||||
|
||||
@in_use = Array.new 256
|
||||
@mtf_freq = Array.new MAX_ALPHA_SIZE, 0
|
||||
@unseq_to_seq = Array.new 256
|
||||
|
||||
@generate_mtf_values_yy = Array.new 256
|
||||
@send_mtf_values_code = Array.new(N_GROUPS) { Array.new MAX_ALPHA_SIZE }
|
||||
@send_mtf_values_cost = Array.new N_GROUPS
|
||||
@send_mtf_values_fave = Array.new N_GROUPS
|
||||
@send_mtf_values_len = Array.new(N_GROUPS) { Array.new MAX_ALPHA_SIZE }
|
||||
@send_mtf_values_rfreq = Array.new(N_GROUPS) { Array.new MAX_ALPHA_SIZE }
|
||||
@send_mtf_values2_pos = Array.new N_GROUPS
|
||||
@send_mtf_values4_in_use_16 = Array.new 16
|
||||
|
||||
@stack_dd = Array.new QSORT_STACK_SIZE
|
||||
@stack_hh = Array.new QSORT_STACK_SIZE
|
||||
@stack_ll = Array.new QSORT_STACK_SIZE
|
||||
|
||||
@main_sort_big_done = Array.new 256
|
||||
@main_sort_copy = Array.new 256
|
||||
@main_sort_running_order = Array.new 256
|
||||
|
||||
@heap = Array.new MAX_ALPHA_SIZE + 2
|
||||
@parent = Array.new MAX_ALPHA_SIZE + 2
|
||||
@weight = Array.new MAX_ALPHA_SIZE + 2
|
||||
|
||||
@ftab = Array.new 65537
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise_archive/resources'
|
||||
require 'poise_archive/archive_providers'
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise_archive/resources/poise_archive'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
# Chef resources and providers for poise-archive.
|
||||
#
|
||||
# @since 1.0.0
|
||||
module Resources
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,151 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'base64'
|
||||
require 'uri'
|
||||
|
||||
require 'chef/resource'
|
||||
require 'poise'
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
module Resources
|
||||
# (see PoiseArchive::Resource)
|
||||
# @since 1.0.0
|
||||
module PoiseArchive
|
||||
# A `poise_archive` resource to unpack archives.
|
||||
#
|
||||
# @provides poise_archive
|
||||
# @action unpack
|
||||
# @example
|
||||
# poise_archive '/opt/myapp.tgz'
|
||||
# @example Downloading from a URL with options
|
||||
# poise_archive ['http://example.com/myapp.zip', {headers: {'Authentication' => '...'}}] do
|
||||
# destination '/opt/myapp'
|
||||
# end
|
||||
class Resource < Chef::Resource
|
||||
include Poise
|
||||
provides(:poise_archive)
|
||||
actions(:unpack)
|
||||
|
||||
# @!attribute path
|
||||
# Path to the archive. If relative, it is taken as a file inside
|
||||
# `Chef::Config[:file_cache_path]`. Can also be a URL to download the
|
||||
# archive from.
|
||||
# @return [String, Array]
|
||||
attribute(:path, kind_of: String, default: lazy { @raw_name.is_a?(Array) ? @raw_name[0] : name }, required: true)
|
||||
# @!attribute destination
|
||||
# Path to unpack the archive to. If not specified, the path of the
|
||||
# archive without the file extension is used.
|
||||
# @return [String, nil, false]
|
||||
attribute(:destination, kind_of: [String, NilClass, FalseClass], default: lazy { default_destination })
|
||||
# @!attribute group
|
||||
# Group to run the unpack as.
|
||||
# @return [String, Integer, nil, false]
|
||||
attribute(:group, kind_of: [String, Integer, NilClass, FalseClass])
|
||||
# @!attribute keep_existing
|
||||
# Keep existing files in the destination directory when unpacking.
|
||||
# @return [Boolean]
|
||||
attribute(:keep_existing, equal_to: [true, false], default: false)
|
||||
# @!attribute source_properties
|
||||
# Properties to pass through to the underlying download resource if
|
||||
# using one. Merged with the array form of {#name}.
|
||||
# @return [Hash]
|
||||
attribute(:source_properties, option_collector: true, forced_keys: %i{retries})
|
||||
# @!attribute strip_components
|
||||
# Number of intermediary directories to skip when unpacking. Works
|
||||
# like GNU tar's --strip-components.
|
||||
# @return [Integer]
|
||||
attribute(:strip_components, kind_of: Integer, default: 1)
|
||||
# @!attribute user
|
||||
# User to run the unpack as.
|
||||
# @return [String, Integer, nil, false]
|
||||
attribute(:user, kind_of: [String, Integer, NilClass, FalseClass])
|
||||
|
||||
# Alias for the forgetful.
|
||||
# @api private
|
||||
alias_method :owner, :user
|
||||
|
||||
def initialize(name, run_context)
|
||||
@raw_name = name # Capture this before it gets coerced to a string.
|
||||
super
|
||||
end
|
||||
|
||||
# Regexp for URL-like paths.
|
||||
# @api private
|
||||
URL_PATHS = %r{^(\w+:)?//}
|
||||
|
||||
# Check if the source path is a URL.
|
||||
#
|
||||
# @api private
|
||||
# @return [Boolean]
|
||||
def is_url?
|
||||
path =~ URL_PATHS
|
||||
end
|
||||
|
||||
# Expand a relative file path against `Chef::Config[:file_cache_path]`.
|
||||
# For URLs it returns the cache file path.
|
||||
#
|
||||
# @api private
|
||||
# @return [String]
|
||||
def absolute_path
|
||||
if is_url?
|
||||
# Use the last path component without the query string plus the name
|
||||
# of the resource in Base64. This should be both mildly readable and
|
||||
# also unique per invocation.
|
||||
url_part = URI(path).path.split(/\//).last
|
||||
base64_name = Base64.strict_encode64(name).gsub(/\=/, '')
|
||||
::File.join(Chef::Config[:file_cache_path], "#{base64_name}_#{url_part}")
|
||||
else
|
||||
::File.expand_path(path, Chef::Config[:file_cache_path])
|
||||
end
|
||||
end
|
||||
|
||||
# Merge the explicit source properties with the array form of the name.
|
||||
#
|
||||
# @api private
|
||||
# @return [Hash]
|
||||
def merged_source_properties
|
||||
if @raw_name.is_a?(Array) && @raw_name[1]
|
||||
source_properties.merge(@raw_name[1])
|
||||
else
|
||||
source_properties
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Filename components to ignore.
|
||||
# @api private
|
||||
BASENAME_IGNORE = /(\.(t?(ar|gz|bz2?|xz)|zip))+$/
|
||||
|
||||
# Default value for the {#destination} property
|
||||
#
|
||||
# @api private
|
||||
# @return [String]
|
||||
def default_destination
|
||||
if is_url?
|
||||
raise ValueError.new("Destination for URL-based archive #{self} must be specified explicitly")
|
||||
else
|
||||
::File.join(::File.dirname(absolute_path), ::File.basename(path).gsub(BASENAME_IGNORE, ''))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Providers can be found in archive_providers/.
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
module PoiseArchive
|
||||
VERSION = '1.5.0'
|
||||
end
|
||||
19
cookbooks/poise-archive/libraries/default.rb
Normal file
19
cookbooks/poise-archive/libraries/default.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright 2016-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load]
|
||||
$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__)
|
||||
require "poise_archive/cheftie"
|
||||
1
cookbooks/poise-archive/metadata.json
Normal file
1
cookbooks/poise-archive/metadata.json
Normal file
@@ -0,0 +1 @@
|
||||
{"name":"poise-archive","version":"1.5.0","description":"A Chef cookbook for unpacking file archives like tar and zip.","long_description":"# Poise-Archive Cookbook\n\n[](https://travis-ci.org/poise/poise-archive)\n[](https://rubygems.org/gems/poise-archive)\n[](https://supermarket.chef.io/cookbooks/poise-archive)\n[](https://codecov.io/github/poise/poise-archive)\n[](https://gemnasium.com/poise/poise-archive)\n[](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to unpack file archives.\n\nIt supports `.tar`, `.tar.gz`, `.tar.bz2`, and `.zip` archive files.\n\n## Quick Start\n\nTo download an unpack and archive:\n\n```ruby\npoise_archive 'https://example.com/myapp.tgz' do\n destination '/opt/myapp'\nend\n```\n\n## Requirements\n\nChef 12.1 or newer is required.\n\n## Platforms\n\nThis cookbook supports all platforms (including Windows) but some Unix platforms\n(Solaris, AIX) may see very slow tar file unpacking when using the pure-Ruby fallback\nimplementation.\n\n## Resources\n\n### `poise_archive`\n\nThe `poise_archive` resource unpacks file archives.\n\n```ruby\npoise_archive '/tmp/myapp-1.2.0.tar' do\n destination '/srv/myapp-1.2.0'\nend\n```\n\nA URL can also be passed as the source path, optionally with extra properties to\nbe merged with `source_properties`.\n\n```ruby\npoise_archive 'http://example.com/myapp-1.2.0.zip' do\n destination '/srv/myapp-1.2.0'\nend\n\npoise_archive ['http://example.com/myapp-1.2.0.zip', {headers: {'Authentication' => '...'}}] do\n destination '/srv/myapp-1.2.0'\nend\n```\n\n#### Actions\n\n* `:unpack` – Unpack the archive. *(default)*\n\n#### Properties\n\n* `path` – Path to the archive. If relative, it is taken as a file inside\n `Chef::Config[:file_cache_path]`. If a URL, it is downloaded to a cache file\n first. *(name attribute)*\n* `destination` – Path to unpack the archive to. If not specified, the path of\n the archive without the file extension is used. Required when unpacking from\n a URL. *(default: auto)*\n* `group` – Group to run the unpack as.\n* `keep_existing` – Keep existing files in the destination directory when\n unpacking. *(default: false)*\n* `source_properties` – Property key/value pairs to be applied to the\n `remote_file` file resource when downloading a URL. *(default: {retries: 5})*\n* `strip_components` – Number of intermediary directories to skip when\n unpacking. Works like GNU tar's `--strip-components`. *(default: 1)*\n* `user` – User to run the unpack as.\n\n## Sponsors\n\nDevelopment sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2016-2017, Noah Kantrowitz\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nBZip2 implementation is based on RBzip2. Copyright Sebastian Staudt, Brian Lopez.\nRBzip2 code used under the terms of the new BSD license.\n","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.6"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-archive","issues_url":"https://github.com/poise/poise-archive/issues","chef_version":[["< 14",">= 12.1"]],"ohai_version":[]}
|
||||
Reference in New Issue
Block a user