knife-essentials 0.4 → 0.5
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.
- data/lib/chef/knife/diff.rb +2 -2
- data/lib/chef/knife/download.rb +16 -1
- data/lib/chef/knife/list.rb +2 -0
- data/lib/chef/knife/show.rb +2 -0
- data/lib/chef/knife/upload.rb +47 -0
- data/lib/chef_fs/file_system.rb +50 -18
- data/lib/chef_fs/file_system/data_bags_dir.rb +11 -0
- data/lib/chef_fs/file_system/rest_list_dir.rb +12 -0
- data/lib/chef_fs/file_system/rest_list_entry.rb +17 -2
- data/lib/chef_fs/version.rb +1 -1
- metadata +3 -2
data/lib/chef/knife/diff.rb
CHANGED
@@ -6,6 +6,8 @@ class Chef
|
|
6
6
|
class Diff < ChefFS::Knife
|
7
7
|
banner "diff PATTERNS"
|
8
8
|
|
9
|
+
common_options
|
10
|
+
|
9
11
|
option :recurse,
|
10
12
|
:long => '--[no-]recurse',
|
11
13
|
:boolean => true,
|
@@ -22,8 +24,6 @@ class Chef
|
|
22
24
|
:boolean => true,
|
23
25
|
:description => "Only show names and statuses of modified files: Added, Deleted, Modified, and Type Changed."
|
24
26
|
|
25
|
-
common_options
|
26
|
-
|
27
27
|
def run
|
28
28
|
if config[:name_only]
|
29
29
|
output_mode = :name_only
|
data/lib/chef/knife/download.rb
CHANGED
@@ -6,6 +6,8 @@ class Chef
|
|
6
6
|
class Download < ChefFS::Knife
|
7
7
|
banner "download PATTERNS"
|
8
8
|
|
9
|
+
common_options
|
10
|
+
|
9
11
|
option :recurse,
|
10
12
|
:long => '--[no-]recurse',
|
11
13
|
:boolean => true,
|
@@ -18,12 +20,25 @@ class Chef
|
|
18
20
|
:default => false,
|
19
21
|
:description => "Delete matching local files and directories that do not exist remotely."
|
20
22
|
|
23
|
+
option :force,
|
24
|
+
:long => '--[no-]force',
|
25
|
+
:boolean => true,
|
26
|
+
:default => false,
|
27
|
+
:description => "Force upload of files even if they match (quicker and harmless, but doesn't print out what it changed)"
|
28
|
+
|
29
|
+
option :dry_run,
|
30
|
+
:long => '--dry-run',
|
31
|
+
:short => '-n',
|
32
|
+
:boolean => true,
|
33
|
+
:default => false,
|
34
|
+
:description => "Don't take action, only print what would happen"
|
35
|
+
|
21
36
|
def run
|
22
37
|
patterns = pattern_args_from(name_args.length > 0 ? name_args : [ "" ])
|
23
38
|
|
24
39
|
# Get the matches (recursively)
|
25
40
|
patterns.each do |pattern|
|
26
|
-
ChefFS::FileSystem.copy_to(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, config
|
41
|
+
ChefFS::FileSystem.copy_to(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, config)
|
27
42
|
end
|
28
43
|
end
|
29
44
|
end
|
data/lib/chef/knife/list.rb
CHANGED
data/lib/chef/knife/show.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'chef_fs/knife'
|
2
|
+
require 'chef_fs/command_line'
|
3
|
+
|
4
|
+
class Chef
|
5
|
+
class Knife
|
6
|
+
class Upload < ChefFS::Knife
|
7
|
+
banner "upload PATTERNS"
|
8
|
+
|
9
|
+
common_options
|
10
|
+
|
11
|
+
option :recurse,
|
12
|
+
:long => '--[no-]recurse',
|
13
|
+
:boolean => true,
|
14
|
+
:default => true,
|
15
|
+
:description => "List directories recursively."
|
16
|
+
|
17
|
+
option :purge,
|
18
|
+
:long => '--[no-]purge',
|
19
|
+
:boolean => true,
|
20
|
+
:default => false,
|
21
|
+
:description => "Delete matching local files and directories that do not exist remotely."
|
22
|
+
|
23
|
+
option :force,
|
24
|
+
:long => '--[no-]force',
|
25
|
+
:boolean => true,
|
26
|
+
:default => false,
|
27
|
+
:description => "Force upload of files even if they match (quicker and harmless, but doesn't print out what it changed)"
|
28
|
+
|
29
|
+
option :dry_run,
|
30
|
+
:long => '--dry-run',
|
31
|
+
:short => '-n',
|
32
|
+
:boolean => true,
|
33
|
+
:default => false,
|
34
|
+
:description => "Don't take action, only print what would happen"
|
35
|
+
|
36
|
+
def run
|
37
|
+
patterns = pattern_args_from(name_args.length > 0 ? name_args : [ "" ])
|
38
|
+
|
39
|
+
# Get the matches (recursively)
|
40
|
+
patterns.each do |pattern|
|
41
|
+
ChefFS::FileSystem.copy_to(pattern, local_fs, chef_fs, config[:recurse] ? nil : 1, config)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
data/lib/chef_fs/file_system.rb
CHANGED
@@ -42,7 +42,7 @@ module ChefFS
|
|
42
42
|
# the entry at the end of the path.
|
43
43
|
#
|
44
44
|
# ==== Attributes
|
45
|
-
#
|
45
|
+
#
|
46
46
|
# * +entry+ - the entry to start looking under. Relative
|
47
47
|
# paths will be resolved from here.
|
48
48
|
# * +path+ - the path to resolve. If it starts with +/+,
|
@@ -72,26 +72,32 @@ module ChefFS
|
|
72
72
|
# given pattern will look identical to src.
|
73
73
|
#
|
74
74
|
# ==== Attributes
|
75
|
-
#
|
75
|
+
#
|
76
76
|
# * +pattern+ - ChefFS::FilePattern to match children under
|
77
77
|
# * +src_root+ - the root from which things will be copied
|
78
78
|
# * +dest_root+ - the root to which things will be copied
|
79
79
|
# * +recurse_depth+ - the maximum depth to copy things. +nil+
|
80
80
|
# means infinite depth. 0 means no recursion.
|
81
|
-
# * +
|
81
|
+
# * +options+ - hash of options:
|
82
|
+
# - +purge+ - if +true+, items in +dest+ that are not in +src+
|
82
83
|
# will be deleted from +dest+. If +false+, these items will
|
83
84
|
# be left alone.
|
85
|
+
# - +force+ - if +true+, matching files are always copied from
|
86
|
+
# +src+ to +dest+. If +false+, they will only be copied if
|
87
|
+
# actually different (which will take time to determine).
|
88
|
+
# - +dry_run+ - if +true+, action will not actually be taken;
|
89
|
+
# things will be printed out instead.
|
84
90
|
#
|
85
91
|
# ==== Examples
|
86
92
|
#
|
87
93
|
# ChefFS::FileSystem.copy_to(FilePattern.new('/cookbooks', chef_fs, local_fs, nil, true)
|
88
94
|
#
|
89
|
-
def self.copy_to(pattern, src_root, dest_root, recurse_depth,
|
95
|
+
def self.copy_to(pattern, src_root, dest_root, recurse_depth, options)
|
90
96
|
found_result = false
|
91
97
|
# Find things we might want to copy
|
92
98
|
ChefFS::Diff::diffable_leaves_from_pattern(pattern, src_root, dest_root, recurse_depth) do |src_leaf, dest_leaf, child_recurse_depth|
|
93
99
|
found_result = true
|
94
|
-
copy_leaves(src_leaf, dest_leaf, child_recurse_depth,
|
100
|
+
copy_leaves(src_leaf, dest_leaf, child_recurse_depth, options)
|
95
101
|
end
|
96
102
|
if !found_result && pattern.exact_path
|
97
103
|
yield "#{pattern}: No such file or directory on remote or local"
|
@@ -101,7 +107,7 @@ module ChefFS
|
|
101
107
|
private
|
102
108
|
|
103
109
|
# Copy two known leaves (could be files or dirs)
|
104
|
-
def self.copy_leaves(src_entry, dest_entry, recurse_depth,
|
110
|
+
def self.copy_leaves(src_entry, dest_entry, recurse_depth, options)
|
105
111
|
# A NOTE about this algorithm:
|
106
112
|
# There are cases where this algorithm does too many network requests.
|
107
113
|
# knife upload with a specific filename will first check if the file
|
@@ -114,11 +120,15 @@ module ChefFS
|
|
114
120
|
# Will need to decide how that works with checksums, though.
|
115
121
|
|
116
122
|
if !src_entry.exists?
|
117
|
-
if purge
|
123
|
+
if options[:purge]
|
118
124
|
# If we would not have uploaded it, we will not purge it.
|
119
125
|
if src_entry.parent.can_have_child?(dest_entry.name, dest_entry.dir?)
|
120
|
-
|
121
|
-
|
126
|
+
if options[:dry_run]
|
127
|
+
puts "Would delete #{dest_entry.path_for_printing}"
|
128
|
+
else
|
129
|
+
dest_entry.delete
|
130
|
+
puts "Delete extra entry #{dest_entry.path_for_printing} (purge is on)"
|
131
|
+
end
|
122
132
|
else
|
123
133
|
Chef::Log.info("Not deleting extra entry #{dest_entry.path_for_printing} (purge is off)")
|
124
134
|
end
|
@@ -127,18 +137,27 @@ module ChefFS
|
|
127
137
|
elsif !dest_entry.exists?
|
128
138
|
if dest_entry.parent.can_have_child?(src_entry.name, src_entry.dir?)
|
129
139
|
if src_entry.dir?
|
130
|
-
|
131
|
-
|
140
|
+
if options[:dry_run]
|
141
|
+
puts "Would create #{dest_entry.path_for_printing}"
|
142
|
+
new_dest_dir = dest_entry.parent.child(src_entry.name)
|
143
|
+
else
|
144
|
+
new_dest_dir = dest_entry.parent.create_child(src_entry.name, nil)
|
145
|
+
puts "Created #{dest_entry.path_for_printing}/"
|
146
|
+
end
|
132
147
|
# Directory creation is recursive.
|
133
148
|
if recurse_depth != 0
|
134
149
|
src_entry.children.each do |src_child|
|
135
150
|
new_dest_child = new_dest_dir.child(src_child.name)
|
136
|
-
copy_leaves(src_child, new_dest_child, recurse_depth ? recurse_depth - 1 : recurse_depth,
|
151
|
+
copy_leaves(src_child, new_dest_child, recurse_depth ? recurse_depth - 1 : recurse_depth, options)
|
137
152
|
end
|
138
153
|
end
|
139
154
|
else
|
140
|
-
|
141
|
-
|
155
|
+
if options[:dry_run]
|
156
|
+
puts "Would create #{dest_entry.path_for_printing}"
|
157
|
+
else
|
158
|
+
dest_entry.parent.create_child(src_entry.name, src_entry.read)
|
159
|
+
puts "Created #{dest_entry.path_for_printing}"
|
160
|
+
end
|
142
161
|
end
|
143
162
|
end
|
144
163
|
|
@@ -159,11 +178,24 @@ module ChefFS
|
|
159
178
|
return
|
160
179
|
else
|
161
180
|
# Both are files! Copy them unless we're sure they are the same.
|
162
|
-
|
163
|
-
|
181
|
+
if options[:force]
|
182
|
+
should_copy = true
|
183
|
+
src_value = src_entry.read
|
184
|
+
else
|
185
|
+
should_copy, src_value, dest_value = ChefFS::Diff.diff_files(src_entry, dest_entry)
|
164
186
|
src_value = src_entry.read if src_value == :not_retrieved
|
165
|
-
|
166
|
-
|
187
|
+
if should_copy == nil
|
188
|
+
should_copy = true
|
189
|
+
end
|
190
|
+
end
|
191
|
+
if should_copy
|
192
|
+
if options[:dry_run]
|
193
|
+
puts "Would update #{dest_entry.path_for_printing}"
|
194
|
+
else
|
195
|
+
src_value = src_entry.read if src_value == :not_retrieved
|
196
|
+
dest_entry.write(src_value)
|
197
|
+
puts "Updated #{dest_entry.path_for_printing}"
|
198
|
+
end
|
167
199
|
end
|
168
200
|
end
|
169
201
|
end
|
@@ -20,6 +20,17 @@ module ChefFS
|
|
20
20
|
def can_have_child?(name, is_dir)
|
21
21
|
is_dir
|
22
22
|
end
|
23
|
+
|
24
|
+
def create_child(name, file_contents)
|
25
|
+
begin
|
26
|
+
rest.post_rest(api_path, { 'name' => name })
|
27
|
+
rescue Net::HTTPServerException
|
28
|
+
if $!.response.code != "409"
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
end
|
32
|
+
DataBagDir.new(name, self, true)
|
33
|
+
end
|
23
34
|
end
|
24
35
|
end
|
25
36
|
end
|
@@ -33,6 +33,18 @@ module ChefFS
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def create_child(name, file_contents)
|
37
|
+
json = Chef::JSONCompat.from_json(file_contents).to_hash
|
38
|
+
base_name = name[0,name.length-5]
|
39
|
+
if json.include?('name') && json['name'] != base_name
|
40
|
+
raise "Name in #{path_for_printing}/#{name} must be '#{base_name}' (is '#{json['name']}')"
|
41
|
+
elsif json.include?('id') && json['id'] != base_name
|
42
|
+
raise "Name in #{path_for_printing}/#{name} must be '#{base_name}' (is '#{json['id']}')"
|
43
|
+
end
|
44
|
+
rest.post_rest(api_path, json)
|
45
|
+
RestListEntry.new(name, self, true)
|
46
|
+
end
|
47
|
+
|
36
48
|
def environment
|
37
49
|
parent.environment
|
38
50
|
end
|
@@ -62,8 +62,23 @@ module ChefFS
|
|
62
62
|
:json
|
63
63
|
end
|
64
64
|
|
65
|
-
def write(
|
66
|
-
|
65
|
+
def write(file_contents)
|
66
|
+
json = Chef::JSONCompat.from_json(file_contents).to_hash
|
67
|
+
base_name = name[0,name.length-5]
|
68
|
+
if json.include?('name') && json['name'] != base_name
|
69
|
+
raise "Name in #{path_for_printing}/#{name} must be '#{base_name}' (is '#{json['name']}')"
|
70
|
+
elsif json.include?('id') && json['id'] != base_name
|
71
|
+
raise "Name in #{path_for_printing}/#{name} must be '#{base_name}' (is '#{json['id']}')"
|
72
|
+
end
|
73
|
+
begin
|
74
|
+
rest.put_rest(api_path, json)
|
75
|
+
rescue Net::HTTPServerException
|
76
|
+
if $!.response.code == "404"
|
77
|
+
raise ChefFS::FileSystem::NotFoundError.new($!), "#{path_for_printing} not found"
|
78
|
+
else
|
79
|
+
raise
|
80
|
+
end
|
81
|
+
end
|
67
82
|
end
|
68
83
|
end
|
69
84
|
end
|
data/lib/chef_fs/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-essentials
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.5'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-10 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: Universal knife verbs that work with your Chef repository
|
15
15
|
email: jkeiser@opscode.com
|
@@ -26,6 +26,7 @@ files:
|
|
26
26
|
- lib/chef/knife/download.rb
|
27
27
|
- lib/chef/knife/list.rb
|
28
28
|
- lib/chef/knife/show.rb
|
29
|
+
- lib/chef/knife/upload.rb
|
29
30
|
- lib/chef_fs/command_line.rb
|
30
31
|
- lib/chef_fs/diff.rb
|
31
32
|
- lib/chef_fs/file_pattern.rb
|