poise-archive 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +8 -2
- data/lib/poise_archive/archive_providers.rb +2 -0
- data/lib/poise_archive/archive_providers/base.rb +6 -4
- data/lib/poise_archive/archive_providers/gnu_tar.rb +82 -0
- data/lib/poise_archive/archive_providers/tar.rb +17 -2
- data/lib/poise_archive/archive_providers/zip.rb +48 -0
- data/lib/poise_archive/resources/poise_archive.rb +10 -3
- data/lib/poise_archive/version.rb +1 -1
- data/test/cookbook/recipes/default.rb +51 -30
- data/test/integration/default/serverspec/default_spec.rb +64 -14
- data/test/spec/archive_providers/gnu_tar_spec.rb +166 -0
- data/test/spec/archive_providers/tar_spec.rb +52 -56
- data/test/spec/resources/poise_archive_spec.rb +67 -3
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba8a642607edf70f9c1cc3c985d6cd70eed6515
|
4
|
+
data.tar.gz: e1e3fa40223be0e015e1dae1e5640c5a839d5077
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d64cb5a421994253e7b5d124250df5c0d020a481e55e7ac4e699ecb6296327f43efe73fa1024bb95c940402435d79f9a1ba333f27d7dfb0b4ec95ac2c35607a
|
7
|
+
data.tar.gz: c54e8439eeb5b38a451636fa728fe59f3da6a9834aa8ed3609654b2e8e88292b785e24d1aafad84c9cae6367dce953f7aaa4496ca37334c577a622991f7491ca
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Poise-Archive Changelog
|
2
2
|
|
3
|
+
## v1.2.0
|
4
|
+
|
5
|
+
* Add back a tar-binary provider called `GnuTar`, used by default on Linux.
|
6
|
+
* Support for ZIP files via RubyZip.
|
7
|
+
* Full Windows support, including with the `user` and `group` properties.
|
8
|
+
|
3
9
|
## v1.1.2
|
4
10
|
|
5
11
|
* Fix compat with older Ruby that doesn't include `Entry#symlink?`.
|
data/README.md
CHANGED
@@ -7,9 +7,9 @@
|
|
7
7
|
[](https://gemnasium.com/poise/poise-archive)
|
8
8
|
[](https://www.apache.org/licenses/LICENSE-2.0)
|
9
9
|
|
10
|
-
A [Chef](https://www.chef.io/) cookbook to unpack file archives
|
10
|
+
A [Chef](https://www.chef.io/) cookbook to unpack file archives.
|
11
11
|
|
12
|
-
|
12
|
+
It supports `.tar`, `.tar.gz`, `.tar.bz2`, and `.zip` archive files.
|
13
13
|
|
14
14
|
## Quick Start
|
15
15
|
|
@@ -27,6 +27,12 @@ remote_file "#{Chef::Config[:file_cache_path]}/myapp.tgz" do
|
|
27
27
|
end
|
28
28
|
```
|
29
29
|
|
30
|
+
## Platforms
|
31
|
+
|
32
|
+
This cookbook supports all platforms (including Windows) but non-Linux platforms
|
33
|
+
may see very slow tar file unpacking when using the pure-Ruby fallback
|
34
|
+
implementation.
|
35
|
+
|
30
36
|
## Resources
|
31
37
|
|
32
38
|
### `poise_archive`
|
@@ -16,6 +16,7 @@
|
|
16
16
|
|
17
17
|
require 'chef/platform/provider_priority_map'
|
18
18
|
|
19
|
+
require 'poise_archive/archive_providers/gnu_tar'
|
19
20
|
require 'poise_archive/archive_providers/tar'
|
20
21
|
require 'poise_archive/archive_providers/zip'
|
21
22
|
|
@@ -27,6 +28,7 @@ module PoiseArchive
|
|
27
28
|
module ArchiveProviders
|
28
29
|
# Set up priority maps
|
29
30
|
Chef::Platform::ProviderPriorityMap.instance.priority(:poise_archive, [
|
31
|
+
PoiseArchive::ArchiveProviders::GnuTar,
|
30
32
|
PoiseArchive::ArchiveProviders::Tar,
|
31
33
|
PoiseArchive::ArchiveProviders::Zip,
|
32
34
|
])
|
@@ -55,11 +55,13 @@ module PoiseArchive
|
|
55
55
|
#
|
56
56
|
# @return [void]
|
57
57
|
def action_unpack
|
58
|
-
|
59
|
-
|
58
|
+
converge_by("unpack archive #{new_resource.path} to #{new_resource.absolute_destination}") do
|
59
|
+
notifying_block do
|
60
|
+
create_directory
|
61
|
+
end
|
62
|
+
empty_directory
|
63
|
+
unpack_archive
|
60
64
|
end
|
61
|
-
empty_directory
|
62
|
-
unpack_archive
|
63
65
|
end
|
64
66
|
|
65
67
|
private
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'fileutils'
|
18
|
+
require 'tmpdir'
|
19
|
+
|
20
|
+
require 'poise_archive/archive_providers/base'
|
21
|
+
|
22
|
+
|
23
|
+
module PoiseArchive
|
24
|
+
module ArchiveProviders
|
25
|
+
# The `gnu_tar` provider class for `poise_archive` to install from TAR
|
26
|
+
# archives using GNU's tar executable.
|
27
|
+
#
|
28
|
+
# @see PoiseArchive::Resources::PoiseArchive::Resource
|
29
|
+
# @provides poise_archive
|
30
|
+
class GnuTar < Base
|
31
|
+
provides_extension(/\.t(ar|gz|bz|xz)/)
|
32
|
+
|
33
|
+
# Only use this if we are on Linux. Everyone else gets the slow Ruby code.
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
def self.provides?(node, _resource)
|
37
|
+
super && node['os'] == 'linux'
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def unpack_archive
|
43
|
+
notifying_block do
|
44
|
+
install_prereqs
|
45
|
+
end
|
46
|
+
unpack_tar
|
47
|
+
end
|
48
|
+
|
49
|
+
# Install any needed prereqs.
|
50
|
+
#
|
51
|
+
# @return [void]
|
52
|
+
def install_prereqs
|
53
|
+
utils = ['tar']
|
54
|
+
utils << 'bzip2' if new_resource.path =~ /\.t?bz/
|
55
|
+
utils << 'xz-utils' if new_resource.path =~ /\.t?xz/
|
56
|
+
# This is a resource.
|
57
|
+
package utils
|
58
|
+
end
|
59
|
+
|
60
|
+
# Unpack the archive and process `strip_components`.
|
61
|
+
#
|
62
|
+
# @return [void]
|
63
|
+
def unpack_tar
|
64
|
+
# Build the tar command.
|
65
|
+
cmd = %w{tar}
|
66
|
+
cmd << "--strip-components=#{new_resource.strip_components}" if new_resource.strip_components && new_resource.strip_components > 0
|
67
|
+
cmd << if new_resource.path =~ /\.t?gz/
|
68
|
+
'-xzvf'
|
69
|
+
elsif new_resource.path =~ /\.t?bz/
|
70
|
+
'-xjvf'
|
71
|
+
elsif new_resource.path =~ /\.t?xz/
|
72
|
+
'-xJvf'
|
73
|
+
else
|
74
|
+
'-xvf'
|
75
|
+
end
|
76
|
+
cmd << new_resource.path
|
77
|
+
poise_shell_out!(cmd, cwd: new_resource.absolute_destination, group: new_resource.group, user: new_resource.user)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -14,7 +14,6 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
-
require 'fileutils'
|
18
17
|
require 'rubygems/package'
|
19
18
|
require 'zlib'
|
20
19
|
|
@@ -41,12 +40,14 @@ module PoiseArchive
|
|
41
40
|
|
42
41
|
def unpack_archive
|
43
42
|
unpack_tar
|
43
|
+
chown_entries if new_resource.user || new_resource.group
|
44
44
|
end
|
45
45
|
|
46
46
|
# Unpack the archive.
|
47
47
|
#
|
48
48
|
# @return [void]
|
49
49
|
def unpack_tar
|
50
|
+
@tar_entry_paths = []
|
50
51
|
tar_each_with_longlink do |entry|
|
51
52
|
entry_name = entry.full_name.split(/\//).drop(new_resource.strip_components).join('/')
|
52
53
|
# If strip_components wiped out the name, don't process this entry.
|
@@ -54,18 +55,20 @@ module PoiseArchive
|
|
54
55
|
dest = ::File.join(new_resource.destination, entry_name)
|
55
56
|
if entry.directory?
|
56
57
|
Dir.mkdir(dest, entry.header.mode)
|
58
|
+
@tar_entry_paths << [:directory, dest]
|
57
59
|
elsif entry.file?
|
58
60
|
::File.open(dest, 'wb', entry.header.mode) do |dest_f|
|
59
61
|
while buf = entry.read(4096)
|
60
62
|
dest_f.write(buf)
|
61
63
|
end
|
62
64
|
end
|
65
|
+
@tar_entry_paths << [:file, dest]
|
63
66
|
elsif entry.header.typeflag == '2' # symlink? is new in Ruby 2.0, apparently.
|
64
67
|
::File.symlink(entry.header.linkname, dest)
|
68
|
+
@tar_entry_paths << [:link, dest]
|
65
69
|
else
|
66
70
|
raise RuntimeError.new("Unknown tar entry type #{entry.header.typeflag.inspect} in #{new_resource.path}")
|
67
71
|
end
|
68
|
-
FileUtils.chown(new_resource.user, new_resource.group, dest)
|
69
72
|
end
|
70
73
|
end
|
71
74
|
|
@@ -138,6 +141,18 @@ module PoiseArchive
|
|
138
141
|
end
|
139
142
|
end
|
140
143
|
|
144
|
+
def chown_entries
|
145
|
+
paths = @tar_entry_paths
|
146
|
+
notifying_block do
|
147
|
+
paths.each do |type, path|
|
148
|
+
send(type, path) do
|
149
|
+
group new_resource.group
|
150
|
+
owner new_resource.user
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
141
156
|
end
|
142
157
|
end
|
143
158
|
end
|
@@ -25,6 +25,54 @@ module PoiseArchive
|
|
25
25
|
# @provides poise_archive
|
26
26
|
class Zip < Base
|
27
27
|
provides_extension(/\.zip$/)
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def unpack_archive
|
32
|
+
check_rubyzip
|
33
|
+
unpack_zip
|
34
|
+
chown_entries if new_resource.user || new_resource.group
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_rubyzip
|
38
|
+
require 'zip'
|
39
|
+
rescue LoadError
|
40
|
+
notifying_block do
|
41
|
+
install_rubyzip
|
42
|
+
end
|
43
|
+
require 'zip'
|
44
|
+
end
|
45
|
+
|
46
|
+
def install_rubyzip
|
47
|
+
chef_gem 'rubyzip'
|
48
|
+
end
|
49
|
+
|
50
|
+
def unpack_zip
|
51
|
+
@zip_entry_paths = []
|
52
|
+
::Zip::File.open(new_resource.path) do |zip_file|
|
53
|
+
zip_file.each do |entry|
|
54
|
+
entry_name = entry.name.split(/\//).drop(new_resource.strip_components).join('/')
|
55
|
+
# If strip_components wiped out the name, don't process this entry.
|
56
|
+
next if entry_name.empty?
|
57
|
+
entry_path = ::File.join(new_resource.destination, entry_name)
|
58
|
+
entry.extract(entry_path)
|
59
|
+
@zip_entry_paths << [entry.directory? ? :directory : entry.file? ? :file : :link, entry_path]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def chown_entries
|
65
|
+
paths = @zip_entry_paths
|
66
|
+
notifying_block do
|
67
|
+
paths.each do |type, path|
|
68
|
+
send(type, path) do
|
69
|
+
group new_resource.group
|
70
|
+
owner new_resource.user
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
28
76
|
end
|
29
77
|
end
|
30
78
|
end
|
@@ -57,19 +57,26 @@ module PoiseArchive
|
|
57
57
|
# like GNU tar's --strip-components.
|
58
58
|
# @return [Integer]
|
59
59
|
attribute(:strip_components, kind_of: Integer, default: 1)
|
60
|
-
# @!attribute
|
60
|
+
# @!attribute user
|
61
61
|
# User to run the unpack as.
|
62
62
|
# @return [String, Integer, nil, false]
|
63
63
|
attribute(:user, kind_of: [String, Integer, NilClass, FalseClass])
|
64
64
|
|
65
|
+
# Alias for the forgetful.
|
66
|
+
# @api private
|
67
|
+
alias_method :owner, :user
|
68
|
+
|
65
69
|
def absolute_path
|
66
70
|
::File.expand_path(path, Chef::Config[:file_cache_path])
|
67
71
|
end
|
68
72
|
|
73
|
+
# Filename components to ignore.
|
74
|
+
# @api private
|
75
|
+
BASENAME_IGNORE = /(\.(t?(ar|gz|bz2?|xz)|zip))+$/
|
76
|
+
|
69
77
|
def absolute_destination
|
70
78
|
destination || begin
|
71
|
-
|
72
|
-
::File.join(::File.dirname(absolute_path), basename.split(/\./).find {|part| !part.empty? } || basename)
|
79
|
+
::File.join(::File.dirname(absolute_path), ::File.basename(path).gsub(BASENAME_IGNORE, ''))
|
73
80
|
end
|
74
81
|
end
|
75
82
|
end
|
@@ -19,49 +19,70 @@ directory '/test' do
|
|
19
19
|
mode '777'
|
20
20
|
end
|
21
21
|
|
22
|
+
# Test user/group.
|
23
|
+
group 'gpoise' do
|
24
|
+
system true
|
25
|
+
end
|
26
|
+
|
27
|
+
user 'poise' do
|
28
|
+
group 'gpoise'
|
29
|
+
system true
|
30
|
+
end
|
31
|
+
|
22
32
|
# Tests for each fixture file.
|
23
|
-
|
24
|
-
|
25
|
-
|
33
|
+
[
|
34
|
+
{ext: 'tar', provider: nil},
|
35
|
+
{ext: 'tar.gz', provider: nil},
|
36
|
+
{ext: 'tar.bz2', provider: nil},
|
37
|
+
{ext: 'zip', provider: nil},
|
38
|
+
{ext: 'tar', provider: PoiseArchive::ArchiveProviders::Tar},
|
39
|
+
{ext: 'tar.gz', provider: PoiseArchive::ArchiveProviders::Tar},
|
40
|
+
{ext: 'tar.bz2', provider: PoiseArchive::ArchiveProviders::Tar},
|
41
|
+
{ext: 'tar', provider: PoiseArchive::ArchiveProviders::GnuTar, only_if: proc { node['os'] == 'linux' }},
|
42
|
+
{ext: 'tar.gz', provider: PoiseArchive::ArchiveProviders::GnuTar, only_if: proc { node['os'] == 'linux' }},
|
43
|
+
{ext: 'tar.bz2', provider: PoiseArchive::ArchiveProviders::GnuTar, only_if: proc { node['os'] == 'linux' }},
|
44
|
+
{ext: 'zip', provider: PoiseArchive::ArchiveProviders::Zip},
|
45
|
+
].each do |test|
|
46
|
+
next if test[:only_if] && !test[:only_if].call
|
47
|
+
test_base = "/test/#{test[:provider].to_s.split('::').last || 'default'}"
|
48
|
+
directory test_base do
|
49
|
+
mode '777'
|
50
|
+
end
|
51
|
+
|
52
|
+
cookbook_file "#{test_base}/myapp-1.0.0.#{test[:ext]}" do
|
53
|
+
source "myapp-1.0.0.#{test[:ext]}"
|
26
54
|
end
|
27
55
|
|
28
|
-
poise_archive "/
|
29
|
-
destination "
|
56
|
+
poise_archive "#{test_base}/myapp-1.0.0.#{test[:ext]}" do
|
57
|
+
destination "#{test_base}/#{test[:ext]}"
|
58
|
+
provider test[:provider] if test[:provider]
|
30
59
|
end
|
31
60
|
|
32
|
-
poise_archive "/
|
33
|
-
path "/
|
34
|
-
destination "
|
61
|
+
poise_archive "#{test_base}/myapp-1.0.0.#{test[:ext]}_0" do
|
62
|
+
path "#{test_base}/myapp-1.0.0.#{test[:ext]}"
|
63
|
+
destination "#{test_base}/#{test[:ext]}_0"
|
64
|
+
provider test[:provider] if test[:provider]
|
35
65
|
strip_components 0
|
36
66
|
end
|
37
67
|
|
38
|
-
poise_archive "/
|
39
|
-
path "/
|
40
|
-
destination "
|
68
|
+
poise_archive "#{test_base}/myapp-1.0.0.#{test[:ext]}_2" do
|
69
|
+
path "#{test_base}/myapp-1.0.0.#{test[:ext]}"
|
70
|
+
destination "#{test_base}/#{test[:ext]}_2"
|
71
|
+
provider test[:provider] if test[:provider]
|
41
72
|
strip_components 2
|
42
73
|
end
|
43
|
-
end
|
44
74
|
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
user 'poise' do
|
52
|
-
group 'poise'
|
53
|
-
system true
|
54
|
-
end
|
55
|
-
|
56
|
-
directory '/test/user' do
|
57
|
-
group 'poise'
|
58
|
-
mode '700'
|
59
|
-
owner 'poise'
|
75
|
+
poise_archive "#{test_base}/myapp-1.0.0.#{test[:ext]}_user" do
|
76
|
+
path "#{test_base}/myapp-1.0.0.#{test[:ext]}"
|
77
|
+
destination "#{test_base}/#{test[:ext]}_user"
|
78
|
+
provider test[:provider] if test[:provider]
|
79
|
+
user 'poise'
|
80
|
+
end
|
60
81
|
end
|
61
82
|
|
62
|
-
|
63
|
-
|
64
|
-
|
83
|
+
# Some general tests for core features.
|
84
|
+
cookbook_file '/test/myapp-1.0.0.tar' do
|
85
|
+
source 'myapp-1.0.0.tar'
|
65
86
|
end
|
66
87
|
|
67
88
|
# Test keep_existing true.
|
@@ -14,8 +14,17 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
+
require 'rbconfig'
|
18
|
+
|
17
19
|
require 'serverspec'
|
18
|
-
|
20
|
+
|
21
|
+
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
22
|
+
set :backend, :cmd
|
23
|
+
set :os, :family => 'windows'
|
24
|
+
else
|
25
|
+
set :backend, :exec
|
26
|
+
end
|
27
|
+
|
19
28
|
|
20
29
|
RSpec.shared_examples 'a poise_archive test' do |ext|
|
21
30
|
base = "/test/#{ext}"
|
@@ -35,28 +44,69 @@ RSpec.shared_examples 'a poise_archive test' do |ext|
|
|
35
44
|
describe file("#{base}_2/main.c") do
|
36
45
|
it { is_expected.to be_a_file }
|
37
46
|
end
|
47
|
+
describe file("#{base}_user") do
|
48
|
+
it { is_expected.to be_owned_by 'poise' }
|
49
|
+
it { is_expected.to be_mode '755' } unless os[:family] == 'windows'
|
50
|
+
end
|
51
|
+
describe file("#{base}_user/README") do
|
52
|
+
it { is_expected.to be_owned_by 'poise' }
|
53
|
+
it { is_expected.to be_mode '644' } unless os[:family] == 'windows'
|
54
|
+
end
|
38
55
|
end
|
39
56
|
|
40
|
-
describe '
|
41
|
-
|
42
|
-
|
57
|
+
describe 'default provider' do
|
58
|
+
describe 'tar' do
|
59
|
+
it_should_behave_like 'a poise_archive test', 'default/tar'
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'tar.gz' do
|
63
|
+
it_should_behave_like 'a poise_archive test', 'default/tar.gz'
|
64
|
+
end
|
43
65
|
|
44
|
-
describe 'tar.
|
45
|
-
|
66
|
+
describe 'tar.bz2' do
|
67
|
+
it_should_behave_like 'a poise_archive test', 'default/tar.bz2'
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'zip' do
|
71
|
+
it_should_behave_like 'a poise_archive test', 'default/zip'
|
72
|
+
end
|
46
73
|
end
|
47
74
|
|
48
|
-
describe '
|
49
|
-
|
75
|
+
describe 'Tar provider' do
|
76
|
+
describe 'tar' do
|
77
|
+
it_should_behave_like 'a poise_archive test', 'Tar/tar'
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'tar.gz' do
|
81
|
+
it_should_behave_like 'a poise_archive test', 'Tar/tar.gz'
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'tar.bz2' do
|
85
|
+
it_should_behave_like 'a poise_archive test', 'Tar/tar.bz2'
|
86
|
+
end
|
50
87
|
end
|
51
88
|
|
52
|
-
describe '
|
53
|
-
describe
|
54
|
-
|
55
|
-
it { is_expected.to be_mode '700' }
|
89
|
+
describe 'GnuTar provider', if: File.exist?('/test/GnuTar') do
|
90
|
+
describe 'tar' do
|
91
|
+
it_should_behave_like 'a poise_archive test', 'GnuTar/tar'
|
56
92
|
end
|
57
|
-
|
58
|
-
|
93
|
+
|
94
|
+
describe 'tar.gz' do
|
95
|
+
it_should_behave_like 'a poise_archive test', 'GnuTar/tar.gz'
|
59
96
|
end
|
97
|
+
|
98
|
+
describe 'tar.bz2' do
|
99
|
+
it_should_behave_like 'a poise_archive test', 'GnuTar/tar.bz2'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe 'Zip provider' do
|
104
|
+
describe 'zip' do
|
105
|
+
it_should_behave_like 'a poise_archive test', 'Zip/zip'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'core features' do
|
60
110
|
describe file('/test/keep/EXISTING') do
|
61
111
|
it { is_expected.to be_a_file }
|
62
112
|
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2016, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'spec_helper'
|
18
|
+
|
19
|
+
FIXTURES_PATH = File.expand_path('../../../cookbook/files', __FILE__)
|
20
|
+
|
21
|
+
describe PoiseArchive::ArchiveProviders::GnuTar do
|
22
|
+
step_into(:poise_archive)
|
23
|
+
let(:archive_provider) { chef_run.poise_archive('myapp').provider_for_action(:unpack) }
|
24
|
+
before do
|
25
|
+
chefspec_options.update(platform: 'ubuntu', version: '14.04')
|
26
|
+
# Stub out some stuff from the base class.
|
27
|
+
expect(Dir).to receive(:mkdir).and_call_original
|
28
|
+
allow(Dir).to receive(:entries).and_call_original
|
29
|
+
allow(Dir).to receive(:entries).with('/test/myapp').and_return(%w{. ..})
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with a .tar path' do
|
33
|
+
recipe do
|
34
|
+
poise_archive 'myapp' do
|
35
|
+
path "/test/myapp-1.0.0.tar"
|
36
|
+
destination '/test/myapp'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it do
|
41
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=1 -xvf /test/myapp-1.0.0.tar}, cwd: '/test/myapp', group: nil, user: nil)
|
42
|
+
run_chef
|
43
|
+
expect(archive_provider).to be_a described_class
|
44
|
+
end
|
45
|
+
end # /context with a .tar path
|
46
|
+
|
47
|
+
context 'with a .tar.gz path' do
|
48
|
+
recipe do
|
49
|
+
poise_archive 'myapp' do
|
50
|
+
path "/test/myapp-1.0.0.tar.gz"
|
51
|
+
destination '/test/myapp'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it do
|
56
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=1 -xzvf /test/myapp-1.0.0.tar.gz}, cwd: '/test/myapp', group: nil, user: nil)
|
57
|
+
run_chef
|
58
|
+
expect(archive_provider).to be_a described_class
|
59
|
+
end
|
60
|
+
end # /context with a .tar.gz path
|
61
|
+
|
62
|
+
context 'with a .tar.bz2 path' do
|
63
|
+
recipe do
|
64
|
+
poise_archive 'myapp' do
|
65
|
+
path "/test/myapp-1.0.0.tar.bz2"
|
66
|
+
destination '/test/myapp'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it do
|
71
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=1 -xjvf /test/myapp-1.0.0.tar.bz2}, cwd: '/test/myapp', group: nil, user: nil)
|
72
|
+
run_chef
|
73
|
+
expect(archive_provider).to be_a described_class
|
74
|
+
end
|
75
|
+
end # /context with a .tar.bz2 path
|
76
|
+
|
77
|
+
context 'with a .tgz path' do
|
78
|
+
recipe do
|
79
|
+
poise_archive 'myapp' do
|
80
|
+
path "/test/myapp-1.0.0.tgz"
|
81
|
+
destination '/test/myapp'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it do
|
86
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=1 -xzvf /test/myapp-1.0.0.tgz}, cwd: '/test/myapp', group: nil, user: nil)
|
87
|
+
run_chef
|
88
|
+
expect(archive_provider).to be_a described_class
|
89
|
+
end
|
90
|
+
end # /context with a .tgz path
|
91
|
+
|
92
|
+
context 'with a .tbz2 path' do
|
93
|
+
recipe do
|
94
|
+
poise_archive 'myapp' do
|
95
|
+
path "/test/myapp-1.0.0.tbz2"
|
96
|
+
destination '/test/myapp'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it do
|
101
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=1 -xjvf /test/myapp-1.0.0.tbz2}, cwd: '/test/myapp', group: nil, user: nil)
|
102
|
+
run_chef
|
103
|
+
expect(archive_provider).to be_a described_class
|
104
|
+
end
|
105
|
+
end # /context with a .tbz2 path
|
106
|
+
|
107
|
+
context 'with strip_components 0' do
|
108
|
+
recipe do
|
109
|
+
poise_archive 'myapp' do
|
110
|
+
path "/test/myapp-1.0.0.tar"
|
111
|
+
destination '/test/myapp'
|
112
|
+
strip_components 0
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it do
|
117
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar -xvf /test/myapp-1.0.0.tar}, cwd: '/test/myapp', group: nil, user: nil)
|
118
|
+
run_chef
|
119
|
+
end
|
120
|
+
end # /context with strip_components 0
|
121
|
+
|
122
|
+
context 'with strip_components 2' do
|
123
|
+
recipe do
|
124
|
+
poise_archive 'myapp' do
|
125
|
+
path "/test/myapp-1.0.0.tar"
|
126
|
+
destination '/test/myapp'
|
127
|
+
strip_components 2
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it do
|
132
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=2 -xvf /test/myapp-1.0.0.tar}, cwd: '/test/myapp', group: nil, user: nil)
|
133
|
+
run_chef
|
134
|
+
end
|
135
|
+
end # /context with strip_components 2
|
136
|
+
|
137
|
+
context 'with a user' do
|
138
|
+
recipe do
|
139
|
+
poise_archive 'myapp' do
|
140
|
+
path "/test/myapp-1.0.0.tar"
|
141
|
+
destination '/test/myapp'
|
142
|
+
user 'myuser'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
it do
|
147
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=1 -xvf /test/myapp-1.0.0.tar}, cwd: '/test/myapp', group: nil, user: 'myuser')
|
148
|
+
run_chef
|
149
|
+
end
|
150
|
+
end # /context with a user
|
151
|
+
|
152
|
+
context 'with a group' do
|
153
|
+
recipe do
|
154
|
+
poise_archive 'myapp' do
|
155
|
+
path "/test/myapp-1.0.0.tar"
|
156
|
+
destination '/test/myapp'
|
157
|
+
group 'mygroup'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
it do
|
162
|
+
expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(%w{tar --strip-components=1 -xvf /test/myapp-1.0.0.tar}, cwd: '/test/myapp', group: 'mygroup', user: nil)
|
163
|
+
run_chef
|
164
|
+
end
|
165
|
+
end # /context with a group
|
166
|
+
end
|
@@ -20,70 +20,66 @@ FIXTURES_PATH = File.expand_path('../../../cookbook/files', __FILE__)
|
|
20
20
|
|
21
21
|
describe PoiseArchive::ArchiveProviders::Tar do
|
22
22
|
step_into(:poise_archive)
|
23
|
+
let(:archive_provider) { chef_run.poise_archive('myapp').provider_for_action(:unpack) }
|
24
|
+
before do
|
25
|
+
expect(Dir).to receive(:mkdir).and_call_original
|
26
|
+
allow(Dir).to receive(:entries).and_call_original
|
27
|
+
allow(Dir).to receive(:entries).with('/test/myapp').and_return(%w{. ..})
|
28
|
+
allow(File).to receive(:open).and_call_original
|
29
|
+
allow(File).to receive(:open).with('/test/myapp-1.0.0.tar', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar')) }
|
30
|
+
allow(File).to receive(:open).with('/test/myapp-1.0.0.tar.gz', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.gz')) }
|
31
|
+
allow(File).to receive(:open).with('/test/myapp-1.0.0.tgz', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.gz')) }
|
32
|
+
allow(File).to receive(:open).with('/test/myapp-1.0.0.tar.bz2', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.bz2')) }
|
33
|
+
allow(File).to receive(:open).with('/test/myapp-1.0.0.tbz2', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.bz2')) }
|
34
|
+
end
|
23
35
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
allow(Dir).to receive(:entries).with('/test/myapp').and_return(%w{. ..})
|
31
|
-
# expect_any_instance_of(described_class).to receive(:poise_shell_out!).with(tar_cmd, cwd: '/test', group: nil, user: nil)
|
32
|
-
# expect_any_instance_of(described_class).to receive(:entries_at_depth).with('/test', 1).and_return(%w{/test/myapp/bin /test/myapp/src})
|
33
|
-
# expect(File).to receive(:rename).with('/test/myapp/bin', '/root/myapp/bin')
|
34
|
-
# expect(File).to receive(:rename).with('/test/myapp/src', '/root/myapp/src')
|
35
|
-
allow(File).to receive(:open).and_call_original
|
36
|
-
allow(File).to receive(:open).with('/test/myapp-1.0.0.tar', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar')) }
|
37
|
-
allow(File).to receive(:open).with('/test/myapp-1.0.0.tar.gz', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.gz')) }
|
38
|
-
allow(File).to receive(:open).with('/test/myapp-1.0.0.tgz', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.gz')) }
|
39
|
-
allow(File).to receive(:open).with('/test/myapp-1.0.0.tar.bz2', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.bz2')) }
|
40
|
-
allow(File).to receive(:open).with('/test/myapp-1.0.0.tbz2', 'rb') { File.open(File.join(FIXTURES_PATH, 'myapp-1.0.0.tar.bz2')) }
|
41
|
-
end
|
42
|
-
|
43
|
-
RSpec.shared_examples 'a poise_archive test' do |ext|
|
44
|
-
recipe do
|
45
|
-
poise_archive 'myapp' do
|
46
|
-
path "/test/myapp-1.0.0.#{ext}"
|
47
|
-
destination '/test/myapp'
|
48
|
-
end
|
36
|
+
RSpec.shared_examples 'a poise_archive tar test' do |ext|
|
37
|
+
recipe do
|
38
|
+
poise_archive 'myapp' do
|
39
|
+
path "/test/myapp-1.0.0.#{ext}"
|
40
|
+
destination '/test/myapp'
|
41
|
+
user 'myuser'
|
49
42
|
end
|
43
|
+
end
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
45
|
+
def expect_file(path, content, mode)
|
46
|
+
fake_file = double("file for #{path}")
|
47
|
+
expect(fake_file).to receive(:write).with(content)
|
48
|
+
allow(File).to receive(:open).with(path, 'wb', mode).and_yield(fake_file)
|
49
|
+
end
|
57
50
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
51
|
+
it do
|
52
|
+
expect_file('/test/myapp/LICENSE', "This is in the public domain.\n", 0644)
|
53
|
+
expect_file('/test/myapp/README', "This is a project!\n\n", 0644)
|
54
|
+
expect(Dir).to receive(:mkdir).with('/test/myapp/src', 0755)
|
55
|
+
expect_file('/test/myapp/src/main.c', "int main(int argc, char **argv)\n{\n return 0;\n}\n\n", 0644)
|
56
|
+
run_chef
|
57
|
+
expect(archive_provider).to be_a described_class
|
58
|
+
expect(chef_run).to create_directory('/test/myapp').with(user: 'myuser', group: nil)
|
59
|
+
expect(chef_run).to create_directory('/test/myapp/src').with(user: 'myuser', group: nil)
|
60
|
+
expect(chef_run).to create_file('/test/myapp/LICENSE').with(user: 'myuser', group: nil)
|
61
|
+
expect(chef_run).to create_file('/test/myapp/README').with(user: 'myuser', group: nil)
|
62
|
+
expect(chef_run).to create_file('/test/myapp/src/main.c').with(user: 'myuser', group: nil)
|
67
63
|
end
|
64
|
+
end
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
context 'with a .tar path' do
|
67
|
+
it_should_behave_like 'a poise_archive tar test', 'tar'
|
68
|
+
end # /context with a .tar path
|
72
69
|
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
context 'with a .tar.gz path' do
|
71
|
+
it_should_behave_like 'a poise_archive tar test', 'tar.gz'
|
72
|
+
end # /context with a .tar.gz path
|
76
73
|
|
77
|
-
|
78
|
-
|
79
|
-
|
74
|
+
context 'with a .tar.bz2 path' do
|
75
|
+
it_should_behave_like 'a poise_archive tar test', 'tar.bz2'
|
76
|
+
end # /context with a .tar.bz2 path
|
80
77
|
|
81
|
-
|
82
|
-
|
83
|
-
|
78
|
+
context 'with a .tgz path' do
|
79
|
+
it_should_behave_like 'a poise_archive tar test', 'tgz'
|
80
|
+
end # /context with a .tgz path
|
84
81
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end # /describe #action_unpack
|
82
|
+
context 'with a .tbz2 path' do
|
83
|
+
it_should_behave_like 'a poise_archive tar test', 'tbz2'
|
84
|
+
end # /context with a .tbz2 path
|
89
85
|
end
|
@@ -69,19 +69,83 @@ describe PoiseArchive::Resources::PoiseArchive do
|
|
69
69
|
end # /context an explicit destination
|
70
70
|
end # /context a relative path
|
71
71
|
|
72
|
-
context 'with
|
72
|
+
context 'with .tar.gz' do
|
73
73
|
recipe do
|
74
74
|
poise_archive '/tmp/myapp.tar.gz'
|
75
75
|
end
|
76
76
|
|
77
77
|
it { is_expected.to unpack_poise_archive('/tmp/myapp.tar.gz').with(absolute_path: '/tmp/myapp.tar.gz', absolute_destination: '/tmp/myapp') }
|
78
|
-
end # /context with
|
78
|
+
end # /context with .tar.gz
|
79
|
+
|
80
|
+
context 'with .tgz' do
|
81
|
+
recipe do
|
82
|
+
poise_archive '/tmp/myapp.tgz'
|
83
|
+
end
|
84
|
+
|
85
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp.tgz').with(absolute_path: '/tmp/myapp.tgz', absolute_destination: '/tmp/myapp') }
|
86
|
+
end # /context with .tgz
|
87
|
+
|
88
|
+
context 'with .tar.bz2' do
|
89
|
+
recipe do
|
90
|
+
poise_archive '/tmp/myapp.tar.bz2'
|
91
|
+
end
|
92
|
+
|
93
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp.tar.bz2').with(absolute_path: '/tmp/myapp.tar.bz2', absolute_destination: '/tmp/myapp') }
|
94
|
+
end # /context with .tar.bz2
|
95
|
+
|
96
|
+
context 'with .tbz2' do
|
97
|
+
recipe do
|
98
|
+
poise_archive '/tmp/myapp.tbz2'
|
99
|
+
end
|
100
|
+
|
101
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp.tbz2').with(absolute_path: '/tmp/myapp.tbz2', absolute_destination: '/tmp/myapp') }
|
102
|
+
end # /context with .tbz2
|
103
|
+
|
104
|
+
context 'with .tar.xz' do
|
105
|
+
recipe do
|
106
|
+
poise_archive '/tmp/myapp.tar.xz'
|
107
|
+
end
|
108
|
+
|
109
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp.tar.xz').with(absolute_path: '/tmp/myapp.tar.xz', absolute_destination: '/tmp/myapp') }
|
110
|
+
end # /context with .tar.xz
|
111
|
+
|
112
|
+
context 'with .txz' do
|
113
|
+
recipe do
|
114
|
+
poise_archive '/tmp/myapp.txz'
|
115
|
+
end
|
116
|
+
|
117
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp.txz').with(absolute_path: '/tmp/myapp.txz', absolute_destination: '/tmp/myapp') }
|
118
|
+
end # /context with .txz
|
119
|
+
|
120
|
+
context 'with .zip' do
|
121
|
+
recipe do
|
122
|
+
poise_archive '/tmp/myapp.zip'
|
123
|
+
end
|
124
|
+
|
125
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp.zip').with(absolute_path: '/tmp/myapp.zip', absolute_destination: '/tmp/myapp') }
|
126
|
+
end # /context with .zip
|
79
127
|
|
80
128
|
context 'with a hidden file' do
|
81
129
|
recipe do
|
82
130
|
poise_archive '/tmp/.myapp.tar'
|
83
131
|
end
|
84
132
|
|
85
|
-
it { is_expected.to unpack_poise_archive('/tmp/.myapp.tar').with(absolute_path: '/tmp/.myapp.tar', absolute_destination: '/tmp
|
133
|
+
it { is_expected.to unpack_poise_archive('/tmp/.myapp.tar').with(absolute_path: '/tmp/.myapp.tar', absolute_destination: '/tmp/.myapp') }
|
86
134
|
end # /context with a hidden file
|
135
|
+
|
136
|
+
context 'with a version number' do
|
137
|
+
recipe do
|
138
|
+
poise_archive '/tmp/myapp-1.0.0.tar'
|
139
|
+
end
|
140
|
+
|
141
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp-1.0.0.tar').with(absolute_path: '/tmp/myapp-1.0.0.tar', absolute_destination: '/tmp/myapp-1.0.0') }
|
142
|
+
end # /context with a version number
|
143
|
+
|
144
|
+
context 'with a version number and .tar.gz' do
|
145
|
+
recipe do
|
146
|
+
poise_archive '/tmp/myapp-1.0.0.tar.gz'
|
147
|
+
end
|
148
|
+
|
149
|
+
it { is_expected.to unpack_poise_archive('/tmp/myapp-1.0.0.tar.gz').with(absolute_path: '/tmp/myapp-1.0.0.tar.gz', absolute_destination: '/tmp/myapp-1.0.0') }
|
150
|
+
end # /context with a version number and .tar.gz
|
87
151
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poise-archive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Kantrowitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: halite
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- lib/poise_archive.rb
|
72
72
|
- lib/poise_archive/archive_providers.rb
|
73
73
|
- lib/poise_archive/archive_providers/base.rb
|
74
|
+
- lib/poise_archive/archive_providers/gnu_tar.rb
|
74
75
|
- lib/poise_archive/archive_providers/tar.rb
|
75
76
|
- lib/poise_archive/archive_providers/zip.rb
|
76
77
|
- lib/poise_archive/bzip2.rb
|
@@ -102,6 +103,7 @@ files:
|
|
102
103
|
- test/gemfiles/chef-12.gemfile
|
103
104
|
- test/gemfiles/master.gemfile
|
104
105
|
- test/integration/default/serverspec/default_spec.rb
|
106
|
+
- test/spec/archive_providers/gnu_tar_spec.rb
|
105
107
|
- test/spec/archive_providers/tar_spec.rb
|
106
108
|
- test/spec/archive_providers/zip_spec.rb
|
107
109
|
- test/spec/resources/poise_archive_spec.rb
|
@@ -148,6 +150,7 @@ test_files:
|
|
148
150
|
- test/gemfiles/chef-12.gemfile
|
149
151
|
- test/gemfiles/master.gemfile
|
150
152
|
- test/integration/default/serverspec/default_spec.rb
|
153
|
+
- test/spec/archive_providers/gnu_tar_spec.rb
|
151
154
|
- test/spec/archive_providers/tar_spec.rb
|
152
155
|
- test/spec/archive_providers/zip_spec.rb
|
153
156
|
- test/spec/resources/poise_archive_spec.rb
|