poise-archive 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-archive.svg)](https://gemnasium.com/poise/poise-archive)
|
8
8
|
[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](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
|