knife-essentials 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|