cheffish 4.0.0 → 4.1.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +8 -8
  3. data/Rakefile +24 -12
  4. data/cheffish.gemspec +15 -15
  5. data/lib/chef/resource/chef_acl.rb +63 -63
  6. data/lib/chef/resource/chef_client.rb +9 -9
  7. data/lib/chef/resource/chef_container.rb +9 -9
  8. data/lib/chef/resource/chef_data_bag.rb +9 -9
  9. data/lib/chef/resource/chef_data_bag_item.rb +27 -27
  10. data/lib/chef/resource/chef_environment.rb +21 -22
  11. data/lib/chef/resource/chef_group.rb +19 -19
  12. data/lib/chef/resource/chef_mirror.rb +32 -17
  13. data/lib/chef/resource/chef_node.rb +14 -14
  14. data/lib/chef/resource/chef_organization.rb +29 -30
  15. data/lib/chef/resource/chef_resolved_cookbooks.rb +7 -7
  16. data/lib/chef/resource/chef_role.rb +25 -22
  17. data/lib/chef/resource/chef_user.rb +13 -14
  18. data/lib/chef/resource/private_key.rb +24 -25
  19. data/lib/chef/resource/public_key.rb +6 -7
  20. data/lib/cheffish.rb +17 -17
  21. data/lib/cheffish/array_property.rb +2 -2
  22. data/lib/cheffish/base_properties.rb +3 -3
  23. data/lib/cheffish/base_resource.rb +8 -8
  24. data/lib/cheffish/basic_chef_client.rb +17 -17
  25. data/lib/cheffish/chef_actor_base.rb +8 -8
  26. data/lib/cheffish/chef_run.rb +7 -2
  27. data/lib/cheffish/chef_run_data.rb +2 -2
  28. data/lib/cheffish/chef_run_listener.rb +1 -1
  29. data/lib/cheffish/key_formatter.rb +16 -18
  30. data/lib/cheffish/merged_config.rb +5 -3
  31. data/lib/cheffish/node_properties.rb +11 -7
  32. data/lib/cheffish/recipe_dsl.rb +33 -34
  33. data/lib/cheffish/rspec.rb +3 -3
  34. data/lib/cheffish/rspec/chef_run_support.rb +13 -13
  35. data/lib/cheffish/rspec/matchers.rb +4 -4
  36. data/lib/cheffish/rspec/matchers/be_idempotent.rb +3 -3
  37. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +3 -3
  38. data/lib/cheffish/rspec/matchers/have_updated.rb +3 -3
  39. data/lib/cheffish/rspec/recipe_run_wrapper.rb +8 -7
  40. data/lib/cheffish/rspec/repository_support.rb +6 -6
  41. data/lib/cheffish/server_api.rb +11 -11
  42. data/lib/cheffish/version.rb +1 -1
  43. data/spec/functional/fingerprint_spec.rb +12 -12
  44. data/spec/functional/merged_config_spec.rb +46 -6
  45. data/spec/functional/server_api_spec.rb +3 -3
  46. data/spec/integration/chef_acl_spec.rb +489 -489
  47. data/spec/integration/chef_client_spec.rb +39 -39
  48. data/spec/integration/chef_container_spec.rb +14 -14
  49. data/spec/integration/chef_data_bag_item_spec.rb +9 -9
  50. data/spec/integration/chef_group_spec.rb +219 -219
  51. data/spec/integration/chef_mirror_spec.rb +228 -228
  52. data/spec/integration/chef_node_spec.rb +511 -511
  53. data/spec/integration/chef_organization_spec.rb +126 -126
  54. data/spec/integration/chef_role_spec.rb +33 -33
  55. data/spec/integration/chef_user_spec.rb +37 -37
  56. data/spec/integration/private_key_spec.rb +154 -154
  57. data/spec/integration/recipe_dsl_spec.rb +10 -10
  58. data/spec/integration/rspec/converge_spec.rb +49 -49
  59. data/spec/support/key_support.rb +6 -6
  60. data/spec/support/spec_support.rb +3 -3
  61. data/spec/unit/get_private_key_spec.rb +19 -19
  62. data/spec/unit/recipe_run_wrapper_spec.rb +4 -4
  63. metadata +3 -3
@@ -1,8 +1,10 @@
1
+ require "chef/mash"
2
+
1
3
  module Cheffish
2
4
  class MergedConfig
3
5
  def initialize(*configs)
4
- @configs = configs
5
- @merge_arrays = {}
6
+ @configs = configs.map { |config| Chef::Mash.from_hash config }
7
+ @merge_arrays = Chef::Mash.new
6
8
  end
7
9
 
8
10
  include Enumerable
@@ -60,7 +62,7 @@ module Cheffish
60
62
  alias_method :has_key?, :key?
61
63
 
62
64
  def keys
63
- configs.map { |c| c.keys }.flatten(1).uniq
65
+ configs.flat_map { |c| c.keys }.uniq
64
66
  end
65
67
 
66
68
  def values
@@ -1,4 +1,4 @@
1
- require 'cheffish/base_properties'
1
+ require "cheffish/base_properties"
2
2
 
3
3
  module Cheffish
4
4
  module NodeProperties
@@ -10,7 +10,7 @@ module Cheffish
10
10
  chef_environment run_context.cheffish.current_environment
11
11
  end
12
12
 
13
- property :name, Cheffish::NAME_REGEX, name_property: true
13
+ property :node_properties_name, Cheffish::NAME_REGEX, name_property: true
14
14
  property :chef_environment, Cheffish::NAME_REGEX
15
15
  property :run_list, Array # We should let them specify it as a series of parameters too
16
16
  property :attributes, Hash
@@ -22,7 +22,7 @@ module Cheffish
22
22
  # end
23
23
  # attribute 'ip_address', :delete
24
24
  attr_accessor :attribute_modifiers
25
- def attribute(attribute_path, value=Chef::NOT_PASSED, &block)
25
+ def attribute(attribute_path, value = Chef::NOT_PASSED, &block)
26
26
  @attribute_modifiers ||= []
27
27
  if value != Chef::NOT_PASSED
28
28
  @attribute_modifiers << [ attribute_path, value ]
@@ -36,7 +36,7 @@ module Cheffish
36
36
  # Patchy tags
37
37
  # tag 'webserver', 'apache', 'myenvironment'
38
38
  def tag(*tags)
39
- attribute 'tags' do |existing_tags|
39
+ attribute "tags" do |existing_tags|
40
40
  existing_tags ||= []
41
41
  tags.each do |tag|
42
42
  if !existing_tags.include?(tag.to_s)
@@ -46,8 +46,9 @@ module Cheffish
46
46
  existing_tags
47
47
  end
48
48
  end
49
+
49
50
  def remove_tag(*tags)
50
- attribute 'tags' do |existing_tags|
51
+ attribute "tags" do |existing_tags|
51
52
  if existing_tags
52
53
  tags.each do |tag|
53
54
  existing_tags.delete(tag.to_s)
@@ -61,10 +62,10 @@ module Cheffish
61
62
  # tags :a, :b, :c # removes all other tags
62
63
  def tags(*tags)
63
64
  if tags.size == 0
64
- attribute('tags')
65
+ attribute("tags")
65
66
  else
66
67
  tags = tags[0] if tags.size == 1 && tags[0].kind_of?(Array)
67
- attribute 'tags', tags.map { |tag| tag.to_s }
68
+ attribute "tags", tags.map { |tag| tag.to_s }
68
69
  end
69
70
  end
70
71
 
@@ -82,6 +83,7 @@ module Cheffish
82
83
  @run_list_modifiers ||= []
83
84
  @run_list_modifiers += recipes.map { |recipe| Chef::RunList::RunListItem.new("recipe[#{recipe}]") }
84
85
  end
86
+
85
87
  def role(*roles)
86
88
  if roles.size == 0
87
89
  raise ArgumentError, "At least one role must be specified"
@@ -89,6 +91,7 @@ module Cheffish
89
91
  @run_list_modifiers ||= []
90
92
  @run_list_modifiers += roles.map { |role| Chef::RunList::RunListItem.new("role[#{role}]") }
91
93
  end
94
+
92
95
  def remove_recipe(*recipes)
93
96
  if recipes.size == 0
94
97
  raise ArgumentError, "At least one recipe must be specified"
@@ -96,6 +99,7 @@ module Cheffish
96
99
  @run_list_removers ||= []
97
100
  @run_list_removers += recipes.map { |recipe| Chef::RunList::RunListItem.new("recipe[#{recipe}]") }
98
101
  end
102
+
99
103
  def remove_role(*roles)
100
104
  if roles.size == 0
101
105
  raise ArgumentError, "At least one role must be specified"
@@ -1,30 +1,29 @@
1
- require 'cheffish'
2
-
3
- require 'chef/version'
4
- require 'chef_zero/server'
5
- require 'chef/chef_fs/chef_fs_data_store'
6
- require 'chef/chef_fs/config'
7
- require 'cheffish/chef_run_data'
8
- require 'cheffish/chef_run_listener'
9
- require 'chef/client'
10
- require 'chef/config'
11
- require 'chef_zero/version'
12
- require 'cheffish/merged_config'
13
- require 'chef/resource/chef_acl'
14
- require 'chef/resource/chef_client'
15
- require 'chef/resource/chef_container'
16
- require 'chef/resource/chef_data_bag'
17
- require 'chef/resource/chef_data_bag_item'
18
- require 'chef/resource/chef_environment'
19
- require 'chef/resource/chef_group'
20
- require 'chef/resource/chef_mirror'
21
- require 'chef/resource/chef_node'
22
- require 'chef/resource/chef_organization'
23
- require 'chef/resource/chef_role'
24
- require 'chef/resource/chef_user'
25
- require 'chef/resource/private_key'
26
- require 'chef/resource/public_key'
27
-
1
+ require "cheffish"
2
+
3
+ require "chef/version"
4
+ require "chef_zero/server"
5
+ require "chef/chef_fs/chef_fs_data_store"
6
+ require "chef/chef_fs/config"
7
+ require "cheffish/chef_run_data"
8
+ require "cheffish/chef_run_listener"
9
+ require "chef/client"
10
+ require "chef/config"
11
+ require "chef_zero/version"
12
+ require "cheffish/merged_config"
13
+ require "chef/resource/chef_acl"
14
+ require "chef/resource/chef_client"
15
+ require "chef/resource/chef_container"
16
+ require "chef/resource/chef_data_bag"
17
+ require "chef/resource/chef_data_bag_item"
18
+ require "chef/resource/chef_environment"
19
+ require "chef/resource/chef_group"
20
+ require "chef/resource/chef_mirror"
21
+ require "chef/resource/chef_node"
22
+ require "chef/resource/chef_organization"
23
+ require "chef/resource/chef_role"
24
+ require "chef/resource/chef_user"
25
+ require "chef/resource/private_key"
26
+ require "chef/resource/public_key"
28
27
 
29
28
  class Chef
30
29
  module DSL
@@ -46,7 +45,7 @@ class Chef
46
45
  end
47
46
 
48
47
  def with_chef_local_server(options, &block)
49
- options[:host] ||= '127.0.0.1'
48
+ options[:host] ||= "127.0.0.1"
50
49
  options[:log_level] ||= Chef::Log.level
51
50
  options[:port] ||= ChefZero::VERSION.to_f >= 2.2 ? 8901.upto(9900) : 8901
52
51
 
@@ -57,7 +56,7 @@ class Chef
57
56
  end
58
57
 
59
58
  # Ensure all paths are given
60
- %w(acl client cookbook container data_bag environment group node role).each do |type|
59
+ %w{acl client cookbook container data_bag environment group node role}.each do |type|
61
60
  # Set the options as symbol keys and then copy to string keys
62
61
  string_key = "#{type}_path"
63
62
  symbol_key = "#{type}_path".to_sym
@@ -66,7 +65,7 @@ class Chef
66
65
  if options[:chef_repo_path].kind_of?(String)
67
66
  Chef::Util::PathHelper.join(options[:chef_repo_path], "#{type}s")
68
67
  else
69
- options[:chef_repo_path].map { |path| Chef::Util::PathHelper.join(path, "#{type}s")}
68
+ options[:chef_repo_path].map { |path| Chef::Util::PathHelper.join(path, "#{type}s") }
70
69
  end
71
70
  end
72
71
 
@@ -97,9 +96,9 @@ class Chef
97
96
  end
98
97
 
99
98
  class Config
100
- default(:profile) { ENV['CHEF_PROFILE'] || 'default' }
99
+ default(:profile) { ENV["CHEF_PROFILE"] || "default" }
101
100
  configurable(:private_keys)
102
- default(:private_key_paths) { [ Chef::Util::PathHelper.join(config_dir, 'keys'), Chef::Util::PathHelper.join(user_home, '.ssh') ] }
101
+ default(:private_key_paths) { [ Chef::Util::PathHelper.join(config_dir, "keys"), Chef::Util::PathHelper.join(user_home, ".ssh") ] }
103
102
  default(:private_key_write_path) { private_key_paths.first }
104
103
  end
105
104
 
@@ -128,9 +127,9 @@ end
128
127
 
129
128
  # Chef 12 moved Chef::Config.path_join to PathHelper.join
130
129
  if Chef::VERSION.to_i >= 12
131
- require 'chef/util/path_helper'
130
+ require "chef/util/path_helper"
132
131
  else
133
- require 'chef/config'
132
+ require "chef/config"
134
133
  class Chef
135
134
  class Util
136
135
  class PathHelper
@@ -1,6 +1,6 @@
1
- require 'cheffish/rspec/chef_run_support'
2
- require 'cheffish/rspec/repository_support'
3
- require 'cheffish/rspec/matchers'
1
+ require "cheffish/rspec/chef_run_support"
2
+ require "cheffish/rspec/repository_support"
3
+ require "cheffish/rspec/matchers"
4
4
 
5
5
  module Cheffish
6
6
  module RSpec
@@ -1,10 +1,10 @@
1
- require 'chef_zero/rspec'
2
- require 'chef/server_api'
3
- require 'cheffish/rspec/repository_support'
4
- require 'uri'
5
- require 'cheffish/chef_run'
6
- require 'cheffish/rspec/recipe_run_wrapper'
7
- require 'cheffish/rspec/matchers'
1
+ require "chef_zero/rspec"
2
+ require "chef/server_api"
3
+ require "cheffish/rspec/repository_support"
4
+ require "uri"
5
+ require "cheffish/chef_run"
6
+ require "cheffish/rspec/recipe_run_wrapper"
7
+ require "cheffish/rspec/matchers"
8
8
 
9
9
  module Cheffish
10
10
  module RSpec
@@ -19,7 +19,7 @@ module Cheffish
19
19
  end
20
20
 
21
21
  def when_the_chef_12_server(*args, **options, &block)
22
- if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new('3.1')
22
+ if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new("3.1")
23
23
  when_the_chef_server(*args, :osc_compat => false, :single_org => false, **options, &block)
24
24
  end
25
25
  end
@@ -37,7 +37,7 @@ module Cheffish
37
37
  end
38
38
 
39
39
  def get(path, *args)
40
- if path[0] == '/'
40
+ if path[0] == "/"
41
41
  path = URI.join(rest.url, path)
42
42
  end
43
43
  rest.get(path, *args)
@@ -47,17 +47,17 @@ module Cheffish
47
47
  {}
48
48
  end
49
49
 
50
- def expect_recipe(str=nil, file=nil, line=nil, &recipe)
50
+ def expect_recipe(str = nil, file = nil, line = nil, &recipe)
51
51
  r = recipe(str, file, line, &recipe)
52
52
  r.converge
53
53
  expect(r)
54
54
  end
55
55
 
56
- def expect_converge(str=nil, file=nil, line=nil, &recipe)
56
+ def expect_converge(str = nil, file = nil, line = nil, &recipe)
57
57
  expect { converge(str, file, line, &recipe) }
58
58
  end
59
59
 
60
- def recipe(str=nil, file=nil, line=nil, &recipe)
60
+ def recipe(str = nil, file = nil, line = nil, &recipe)
61
61
  if !recipe
62
62
  if file && line
63
63
  recipe = proc { eval(str, nil, file, line) }
@@ -68,7 +68,7 @@ module Cheffish
68
68
  RecipeRunWrapper.new(chef_config, &recipe)
69
69
  end
70
70
 
71
- def converge(str=nil, file=nil, line=nil, &recipe)
71
+ def converge(str = nil, file = nil, line = nil, &recipe)
72
72
  r = recipe(str, file, line, &recipe)
73
73
  r.converge
74
74
  r
@@ -1,4 +1,4 @@
1
- require 'cheffish/rspec/matchers/have_updated'
2
- require 'cheffish/rspec/matchers/be_idempotent'
3
- require 'cheffish/rspec/matchers/partially_match'
4
- require 'cheffish/rspec/matchers/emit_no_warnings_or_errors'
1
+ require "cheffish/rspec/matchers/have_updated"
2
+ require "cheffish/rspec/matchers/be_idempotent"
3
+ require "cheffish/rspec/matchers/partially_match"
4
+ require "cheffish/rspec/matchers/emit_no_warnings_or_errors"
@@ -1,4 +1,4 @@
1
- require 'rspec/matchers'
1
+ require "rspec/matchers"
2
2
 
3
3
  RSpec::Matchers.define :be_idempotent do
4
4
  match do |recipe|
@@ -8,9 +8,9 @@ RSpec::Matchers.define :be_idempotent do
8
8
  recipe.up_to_date?
9
9
  end
10
10
 
11
- failure_message {
11
+ failure_message do
12
12
  "#{@recipe} is not idempotent! Converging it a second time caused updates.\n#{@recipe.output_for_failure_message}"
13
- }
13
+ end
14
14
 
15
15
  supports_block_expectations
16
16
  end
@@ -1,4 +1,4 @@
1
- require 'rspec/matchers'
1
+ require "rspec/matchers"
2
2
 
3
3
  RSpec::Matchers.define :emit_no_warnings_or_errors do
4
4
  match do |recipe|
@@ -7,9 +7,9 @@ RSpec::Matchers.define :emit_no_warnings_or_errors do
7
7
  @warn_err.empty?
8
8
  end
9
9
 
10
- failure_message {
10
+ failure_message do
11
11
  "#{@recipe} emitted warnings and errors!\n#{@warn_err}"
12
- }
12
+ end
13
13
 
14
14
  supports_block_expectations
15
15
  end
@@ -1,4 +1,4 @@
1
- require 'rspec/matchers'
1
+ require "rspec/matchers"
2
2
 
3
3
  RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
4
4
  match do |recipe|
@@ -14,7 +14,7 @@ RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
14
14
  updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
15
15
  result = "expected that the chef_run would #{expected_actions.join(',')} #{resource_name}."
16
16
  if updates.size > 0
17
- result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
17
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource} => #{action.inspect}" }.join(', ')}"
18
18
  else
19
19
  result << " Nothing was updated."
20
20
  end
@@ -26,7 +26,7 @@ RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
26
26
  updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
27
27
  result = "expected that the chef_run would not #{expected_actions.join(',')} #{resource_name}."
28
28
  if updates.size > 0
29
- result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
29
+ result << " Actual updates were #{updates.map { |event, resource, action| "#{resource} => #{action.inspect}" }.join(', ')}"
30
30
  else
31
31
  result << " Nothing was updated."
32
32
  end
@@ -1,5 +1,5 @@
1
- require 'cheffish/chef_run'
2
- require 'forwardable'
1
+ require "cheffish/chef_run"
2
+ require "forwardable"
3
3
 
4
4
  module Cheffish
5
5
  module RSpec
@@ -7,7 +7,7 @@ module Cheffish
7
7
  def initialize(chef_config, example: nil, &recipe)
8
8
  super(chef_config)
9
9
  @recipe = recipe
10
- @example = example || recipe.binding.eval('self')
10
+ @example = example || recipe.binding.eval("self")
11
11
  end
12
12
 
13
13
  attr_reader :recipe
@@ -29,14 +29,14 @@ module Cheffish
29
29
  # 12.3-ish resource or we want to call a `let` variable.
30
30
  #
31
31
  @client.instance_eval { @rspec_example = example }
32
- def @client.method_missing(name, *args, &block)
32
+ def @client.method_missing(name, *args, &block) # rubocop:disable Lint/NestedMethodDefinition
33
33
  # If there is a let variable, call it. This is because in 12.4,
34
34
  # the parent class is going to call respond_to?(name) to find out
35
35
  # if someone was doing weird things, and then call send(). This
36
36
  # would result in an infinite loop, coming right. Back. Here.
37
37
  # A fix to chef is incoming, but we still need this if we want to
38
38
  # work with Chef 12.4.
39
- if Gem::Version.new(Chef::VERSION) >= Gem::Version.new('12.4')
39
+ if Gem::Version.new(Chef::VERSION) >= Gem::Version.new("12.4")
40
40
  if @rspec_example.respond_to?(name)
41
41
  return @rspec_example.public_send(name, *args, &block)
42
42
  end
@@ -55,9 +55,10 @@ module Cheffish
55
55
  end
56
56
  end
57
57
  end
58
+
58
59
  # This is called by respond_to?, and is required to make sure the
59
60
  # resource knows that we will in fact call the given method.
60
- def @client.respond_to_missing?(name, include_private = false)
61
+ def @client.respond_to_missing?(name, include_private = false) # rubocop:disable Lint/NestedMethodDefinition
61
62
  @rspec_example.respond_to?(name, include_private) || super
62
63
  end
63
64
 
@@ -65,7 +66,7 @@ module Cheffish
65
66
  # will hook resources up to the example let variables as well (via
66
67
  # enclosing_provider).
67
68
  # Please don't hurt me
68
- def @client.is_a?(klass)
69
+ def @client.is_a?(klass) # rubocop:disable Lint/NestedMethodDefinition
69
70
  klass == Chef::Provider || super(klass)
70
71
  end
71
72
 
@@ -12,9 +12,9 @@ module Cheffish
12
12
  ::RSpec.shared_context "with a chef repo" do
13
13
  before :each do
14
14
  raise "Can only create one directory per test" if @repository_dir
15
- @repository_dir = Dir.mktmpdir('chef_repo')
15
+ @repository_dir = Dir.mktmpdir("chef_repo")
16
16
  Chef::Config.chef_repo_path = @repository_dir
17
- %w(client cookbook data_bag environment node role user).each do |object_name|
17
+ %w{client cookbook data_bag environment node role user}.each do |object_name|
18
18
  Chef::Config.delete("#{object_name}_path".to_sym)
19
19
  end
20
20
  end
@@ -22,7 +22,7 @@ module Cheffish
22
22
  after :each do
23
23
  if @repository_dir
24
24
  begin
25
- %w(client cookbook data_bag environment node role user).each do |object_name|
25
+ %w{client cookbook data_bag environment node role user}.each do |object_name|
26
26
  Chef::Config.delete("#{object_name}_path".to_sym)
27
27
  end
28
28
  Chef::Config.delete(:chef_repo_path)
@@ -45,8 +45,8 @@ module Cheffish
45
45
  def file(relative_path, contents)
46
46
  filename = path_to(relative_path)
47
47
  dir = File.dirname(filename)
48
- FileUtils.mkdir_p(dir) unless dir == '.'
49
- File.open(filename, 'w') do |file|
48
+ FileUtils.mkdir_p(dir) unless dir == "."
49
+ File.open(filename, "w") do |file|
50
50
  raw = case contents
51
51
  when Hash, Array
52
52
  JSON.pretty_generate(contents)
@@ -60,7 +60,7 @@ module Cheffish
60
60
  def symlink(relative_path, relative_dest)
61
61
  filename = path_to(relative_path)
62
62
  dir = File.dirname(filename)
63
- FileUtils.mkdir_p(dir) unless dir == '.'
63
+ FileUtils.mkdir_p(dir) unless dir == "."
64
64
  dest_filename = path_to(relative_dest)
65
65
  File.symlink(dest_filename, filename)
66
66
  end