knife-tar 1.3.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 +7 -0
- data/Gemfile +5 -0
- data/README.md +281 -0
- data/Rakefile +60 -0
- data/lib/chef/knife/client_tar_download.rb +40 -0
- data/lib/chef/knife/client_tar_upload.rb +49 -0
- data/lib/chef/knife/cookbook_tar_download.rb +49 -0
- data/lib/chef/knife/cookbook_tar_upload.rb +178 -0
- data/lib/chef/knife/data_bag_tar_download.rb +44 -0
- data/lib/chef/knife/data_bag_tar_upload.rb +53 -0
- data/lib/chef/knife/environment_tar_download.rb +44 -0
- data/lib/chef/knife/environment_tar_upload.rb +36 -0
- data/lib/chef/knife/node_tar_download.rb +40 -0
- data/lib/chef/knife/node_tar_upload.rb +37 -0
- data/lib/chef/knife/role_tar_download.rb +40 -0
- data/lib/chef/knife/role_tar_upload.rb +36 -0
- data/lib/chef/knife/tar_download_all.rb +36 -0
- data/lib/chef/knife/tar_upload_all.rb +70 -0
- data/lib/chef/knife/user_tar_download.rb +40 -0
- data/lib/chef/knife/user_tar_upload.rb +49 -0
- data/lib/chef/tar_file.rb +276 -0
- data/lib/tmp_directory.rb +25 -0
- metadata +95 -0
@@ -0,0 +1,276 @@
|
|
1
|
+
|
2
|
+
require 'open-uri'
|
3
|
+
require 'chef/mixin/command'
|
4
|
+
require 'tmp_directory'
|
5
|
+
|
6
|
+
#A class for handling a tar file that contains chef components.
|
7
|
+
|
8
|
+
class Chef
|
9
|
+
class TarFile
|
10
|
+
|
11
|
+
#The named conventions for chef components
|
12
|
+
COOKBOOKS_PATH = "cookbooks"
|
13
|
+
ROLES_PATH = "roles"
|
14
|
+
ENVIRONMENTS_PATH = "environments"
|
15
|
+
DATA_BAGS_PATH = "data_bags"
|
16
|
+
API_CLIENTS_PATH = "api_clients"
|
17
|
+
WEB_USERS_PATH = "web_users"
|
18
|
+
NODES_PATH = "nodes"
|
19
|
+
|
20
|
+
#A list of valid chef file extensions
|
21
|
+
CHEF_FILE_EXTENSIONS = [".js", ".json", ".rb"]
|
22
|
+
|
23
|
+
def initialize tarPath, create=false
|
24
|
+
|
25
|
+
if tarPath==nil
|
26
|
+
raise ArgumentError, "A tar file path must be given"
|
27
|
+
end
|
28
|
+
|
29
|
+
@create_tar = create
|
30
|
+
|
31
|
+
unless create
|
32
|
+
@temp_directory = TmpDirectory.new.path
|
33
|
+
|
34
|
+
#Assume for now that the components live directly inside the tar file
|
35
|
+
@tar_contents_path = @temp_directory
|
36
|
+
|
37
|
+
localTarFile = File.join(@temp_directory, 'cookbooks.tgz')
|
38
|
+
|
39
|
+
#Move/Download tar file to tmp directory
|
40
|
+
File.open(localTarFile, 'wb') do |f|
|
41
|
+
open(tarPath) do |r|
|
42
|
+
f.write(r.read)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#Untar file
|
47
|
+
Chef::Mixin::Command.run_command(:command => "tar zxfC #{localTarFile} #{@temp_directory}")
|
48
|
+
|
49
|
+
#Verify tar file structure and update tar_contents_path if necessary
|
50
|
+
|
51
|
+
dirList = get_directories_names @tar_contents_path
|
52
|
+
|
53
|
+
if !is_tar_valid? dirList
|
54
|
+
#The tar does not contain any immediate chef component directories, check to see if there is a top-level project folder
|
55
|
+
#that contains any chef component directories
|
56
|
+
|
57
|
+
if dirList.size!=1 or !is_tar_valid? get_directories_names(File.join(@tar_contents_path, dirList.first))
|
58
|
+
raise InvalidStructureError, "The tar file has an invalid structure"
|
59
|
+
end
|
60
|
+
|
61
|
+
#The tar file is valid but contains a top-level project folder so update the @tar_contents_path
|
62
|
+
@tar_contents_path = File.join(@tar_contents_path, dirList.first)
|
63
|
+
end
|
64
|
+
|
65
|
+
#Remove tar file
|
66
|
+
FileUtils.rm_f localTarFile
|
67
|
+
|
68
|
+
else
|
69
|
+
|
70
|
+
# Verify that the tarPath doesn't already exist
|
71
|
+
if File.exists? tarPath
|
72
|
+
raise ArgumentError, "We cannot create a tar file at path : #{tarPath} because it already exists"
|
73
|
+
end
|
74
|
+
|
75
|
+
@temp_directory = TmpDirectory.new("chef-server").path
|
76
|
+
|
77
|
+
#We will create the tar file such that their is no single root directory inside the tar file
|
78
|
+
@tar_contents_path = @temp_directory
|
79
|
+
|
80
|
+
FileUtils.mkdir_p @temp_directory
|
81
|
+
|
82
|
+
@create_tar_path = File.absolute_path tarPath
|
83
|
+
|
84
|
+
# We are setting up a directory to become a Chef TarFile so create the resource directories
|
85
|
+
FileUtils.mkdir_p File.join @tar_contents_path, COOKBOOKS_PATH
|
86
|
+
FileUtils.mkdir_p File.join @tar_contents_path, ROLES_PATH
|
87
|
+
FileUtils.mkdir_p File.join @tar_contents_path, ENVIRONMENTS_PATH
|
88
|
+
FileUtils.mkdir_p File.join @tar_contents_path, DATA_BAGS_PATH
|
89
|
+
FileUtils.mkdir_p File.join @tar_contents_path, API_CLIENTS_PATH
|
90
|
+
FileUtils.mkdir_p File.join @tar_contents_path, WEB_USERS_PATH
|
91
|
+
FileUtils.mkdir_p File.join @tar_contents_path, NODES_PATH
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
#Returns the absolute path to the cookbooks directory
|
98
|
+
def cookbooks_path
|
99
|
+
verify_path COOKBOOKS_PATH
|
100
|
+
File.join @tar_contents_path, COOKBOOKS_PATH
|
101
|
+
end
|
102
|
+
|
103
|
+
#Returns list of absolute paths of the cookbooks
|
104
|
+
def cookbooks
|
105
|
+
get_directories_absolute_paths cookbooks_path
|
106
|
+
end
|
107
|
+
|
108
|
+
#Returns the absolute path to the roles directory
|
109
|
+
def roles_path
|
110
|
+
verify_path ROLES_PATH
|
111
|
+
File.join @tar_contents_path, ROLES_PATH
|
112
|
+
end
|
113
|
+
|
114
|
+
#Returns a list of absolute paths to the roles json files
|
115
|
+
def roles
|
116
|
+
get_chef_files_absolute_paths roles_path
|
117
|
+
end
|
118
|
+
|
119
|
+
#Returns the absolute path to the environments directory
|
120
|
+
def environments_path
|
121
|
+
verify_path ENVIRONMENTS_PATH
|
122
|
+
File.join @tar_contents_path, ENVIRONMENTS_PATH
|
123
|
+
end
|
124
|
+
|
125
|
+
#Returns a list of absolute paths to the environemnts json files
|
126
|
+
def environments
|
127
|
+
get_chef_files_absolute_paths environments_path
|
128
|
+
end
|
129
|
+
|
130
|
+
#Returns the absolute path to the data_bags directory
|
131
|
+
def data_bags_path
|
132
|
+
verify_path DATA_BAGS_PATH
|
133
|
+
File.join @tar_contents_path, DATA_BAGS_PATH
|
134
|
+
end
|
135
|
+
|
136
|
+
#Returns a list of absolute paths to the data_bags json files
|
137
|
+
def data_bags
|
138
|
+
|
139
|
+
#Data bags follow a different structure then the other components, their structure is
|
140
|
+
#|- data_bags
|
141
|
+
#\ \- data_bag_1
|
142
|
+
#| | |- values_1.json
|
143
|
+
#| ...
|
144
|
+
|
145
|
+
dir_list = get_directories_absolute_paths(data_bags_path)
|
146
|
+
|
147
|
+
data_bags_absolute_paths = Array.new
|
148
|
+
|
149
|
+
dir_list.each do |dir_path|
|
150
|
+
data_bags_absolute_paths = data_bags_absolute_paths | get_chef_files_absolute_paths(dir_path)
|
151
|
+
end
|
152
|
+
|
153
|
+
data_bags_absolute_paths
|
154
|
+
end
|
155
|
+
|
156
|
+
#Returns the absolute path to the api_clients directory
|
157
|
+
def api_clients_path
|
158
|
+
verify_path API_CLIENTS_PATH
|
159
|
+
File.join @tar_contents_path, API_CLIENTS_PATH
|
160
|
+
end
|
161
|
+
|
162
|
+
#Returns a list of absolute paths to the api_clients json files
|
163
|
+
def api_clients
|
164
|
+
get_chef_files_absolute_paths api_clients_path
|
165
|
+
end
|
166
|
+
|
167
|
+
#Returns the absolute path of the nodes directory
|
168
|
+
def nodes_path
|
169
|
+
verify_path NODES_PATH
|
170
|
+
File.join @tar_contents_path, NODES_PATH
|
171
|
+
end
|
172
|
+
|
173
|
+
#Returns a list of absolute paths to the nodes json files
|
174
|
+
def nodes
|
175
|
+
get_chef_files_absolute_paths nodes_path
|
176
|
+
end
|
177
|
+
|
178
|
+
#Returns the absolute path of the web_users directory
|
179
|
+
def web_users_path
|
180
|
+
verify_path WEB_USERS_PATH
|
181
|
+
File.join @tar_contents_path, WEB_USERS_PATH
|
182
|
+
end
|
183
|
+
|
184
|
+
#Returns a list of absolute paths to the web_users json files
|
185
|
+
def web_users
|
186
|
+
get_chef_files_absolute_paths web_users_path
|
187
|
+
end
|
188
|
+
|
189
|
+
def save
|
190
|
+
if @create_tar
|
191
|
+
|
192
|
+
#Tar up the directory from the parent directory of the tar's contents (this will really be /tmp)
|
193
|
+
Chef::Mixin::Command.run_command(:cwd => File.expand_path("..",@tar_contents_path), :command => "tar zfc #{@create_tar_path} #{File.basename @tar_contents_path}")
|
194
|
+
|
195
|
+
@create_tar = false
|
196
|
+
else
|
197
|
+
raise StandardError, "The tar file is not in the correct state to be saved"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
private
|
202
|
+
|
203
|
+
#Returns true if the list of directories contains at least one chef component
|
204
|
+
def is_tar_valid? dir_list
|
205
|
+
|
206
|
+
#Remove unnessary directories
|
207
|
+
dir_list.delete(".")
|
208
|
+
dir_list.delete("..")
|
209
|
+
|
210
|
+
dir_list.each do |dir|
|
211
|
+
[API_CLIENTS_PATH, COOKBOOKS_PATH, DATA_BAGS_PATH, ENVIRONMENTS_PATH, NODES_PATH, ROLES_PATH, WEB_USERS_PATH].each do |component|
|
212
|
+
if dir == component
|
213
|
+
return true
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
return false
|
218
|
+
end
|
219
|
+
|
220
|
+
#Throws an exception if the given component does not exist within the tar's contents
|
221
|
+
def verify_path component
|
222
|
+
if !File.exists? File.join @tar_contents_path, component
|
223
|
+
raise MissingChefComponentError, "The '#{component}' directory does not exist within the tar file"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
#Returns a list of the base file names for all the directories at the given path
|
228
|
+
def get_directories_names path
|
229
|
+
get_directories_absolute_paths(path).map {|dir| File.basename(dir) }
|
230
|
+
end
|
231
|
+
|
232
|
+
#Returns a list of the absolute paths of all the directories at the given path
|
233
|
+
def get_directories_absolute_paths path
|
234
|
+
dir_list = Dir["#{path}/*/"]
|
235
|
+
|
236
|
+
#Remove unnecessary directories
|
237
|
+
dir_list.delete(File.join(path, "."))
|
238
|
+
dir_list.delete(File.join(path, ".."))
|
239
|
+
|
240
|
+
dir_list
|
241
|
+
end
|
242
|
+
|
243
|
+
#Returns a list of the base file names for all files at the given path
|
244
|
+
def get_file_names path
|
245
|
+
Dir.entries(path).select { |file| !File.directory? File.join(path, file) }
|
246
|
+
end
|
247
|
+
|
248
|
+
#Returns a list of the absolute paths of all the files at the given path
|
249
|
+
def get_file_absolute_paths path
|
250
|
+
get_file_names(path).map { |file| File.join(path, file) }
|
251
|
+
end
|
252
|
+
|
253
|
+
#Returns a list of the absolute paths of all the valid chef component files at the given path
|
254
|
+
def get_chef_files_absolute_paths path
|
255
|
+
get_file_absolute_paths(path).select { |file| is_valid_chef_component_file?(file) }
|
256
|
+
end
|
257
|
+
|
258
|
+
#Returns true if the filename is a valid chef component file
|
259
|
+
def is_valid_chef_component_file? filename
|
260
|
+
extension = File.extname(filename)
|
261
|
+
CHEF_FILE_EXTENSIONS.each do |validExtension|
|
262
|
+
if extension.casecmp(validExtension) == 0
|
263
|
+
return true
|
264
|
+
end
|
265
|
+
end
|
266
|
+
return false
|
267
|
+
end
|
268
|
+
|
269
|
+
#Error when a Chef::TarFile does not have the correct structure
|
270
|
+
class InvalidStructureError < StandardError; end
|
271
|
+
|
272
|
+
#Error thrown when a chef component that is accessed cannot be found
|
273
|
+
class MissingChefComponentError < StandardError; end
|
274
|
+
|
275
|
+
end
|
276
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
class TmpDirectory
|
4
|
+
|
5
|
+
attr_reader :path
|
6
|
+
|
7
|
+
def initialize name="tmp"
|
8
|
+
@path = ::File.join(Dir.tmpdir, "#{name}-#{Time.now.strftime("%Y%m%d%H%M%S")}-#{Random.rand}")
|
9
|
+
|
10
|
+
FileUtils.mkdir_p @path
|
11
|
+
|
12
|
+
#Add shutdown hook to remove tar tmp directory
|
13
|
+
Kernel.at_exit do
|
14
|
+
cleanup
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
#Remove the created temp directory
|
21
|
+
def cleanup
|
22
|
+
FileUtils.rm_rf @path
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: knife-tar
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bryan Baugher
|
8
|
+
- Aaron Blythe
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: chef
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 0.10.0
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.10.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.9.2.2
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 0.9.2.2
|
42
|
+
description: This is a knife plugin for Chef which can install and upload chef components
|
43
|
+
from a tar file or url
|
44
|
+
email: Bryan.Baugher@Cerner.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- lib/chef/knife/client_tar_download.rb
|
50
|
+
- lib/chef/knife/client_tar_upload.rb
|
51
|
+
- lib/chef/knife/cookbook_tar_download.rb
|
52
|
+
- lib/chef/knife/cookbook_tar_upload.rb
|
53
|
+
- lib/chef/knife/data_bag_tar_download.rb
|
54
|
+
- lib/chef/knife/data_bag_tar_upload.rb
|
55
|
+
- lib/chef/knife/environment_tar_download.rb
|
56
|
+
- lib/chef/knife/environment_tar_upload.rb
|
57
|
+
- lib/chef/knife/node_tar_download.rb
|
58
|
+
- lib/chef/knife/node_tar_upload.rb
|
59
|
+
- lib/chef/knife/role_tar_download.rb
|
60
|
+
- lib/chef/knife/role_tar_upload.rb
|
61
|
+
- lib/chef/knife/tar_download_all.rb
|
62
|
+
- lib/chef/knife/tar_upload_all.rb
|
63
|
+
- lib/chef/knife/user_tar_download.rb
|
64
|
+
- lib/chef/knife/user_tar_upload.rb
|
65
|
+
- lib/chef/tar_file.rb
|
66
|
+
- lib/tmp_directory.rb
|
67
|
+
- Gemfile
|
68
|
+
- Rakefile
|
69
|
+
- README.md
|
70
|
+
homepage: http://github.com/Cerner/knife-tar
|
71
|
+
licenses:
|
72
|
+
- Apache License, Version 2.0
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 2.0.3
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: A Chef knife plugin to install/upload chef components from a tar file or
|
94
|
+
url
|
95
|
+
test_files: []
|