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:
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
|
||||
Reference in New Issue
Block a user