filecluster 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,6 +8,7 @@ module FC
8
8
  # Create item by local path.
9
9
  # Additional options:
10
10
  # :replace=true - replace item if it exists
11
+ # :remove_local=true - delete local_path file/dir after add
11
12
  # If item_name is part of local_path it processed as inplace - local_path is valid path to the item for policy
12
13
  def self.create_from_local(local_path, item_name, policy, options={})
13
14
  raise 'Path not exists' unless File.exists?(local_path)
@@ -20,7 +21,7 @@ module FC
20
21
  :md5 => FC::Storage.new(:host => FC::Storage.curr_host).md5_sum(local_path)
21
22
  })
22
23
  item_params.delete(:replace)
23
- item_params.delete(:inplace)
24
+ item_params.delete(:remove_local)
24
25
  raise 'Name is empty' if item_params[:name].empty?
25
26
  raise 'Zero size path' if item_params[:size] == 0
26
27
 
@@ -49,14 +50,14 @@ module FC
49
50
  item_storage = item.make_item_storage(storage, 'ready')
50
51
  item.reload
51
52
  else
52
- storage = policy.get_proper_storage_for_create(item.size, File.realdirpath(local_path))
53
+ storage = policy.get_proper_storage_for_create(item.size, local_path)
53
54
  FC::Error.raise 'No available storage', :item_id => item.id unless storage
54
55
 
55
56
  # mark delete item_storages on replace
56
57
  FC::DB.query("UPDATE #{FC::ItemStorage.table_name} SET status='delete' WHERE item_id = #{item.id} AND storage_name <> '#{storage.name}'") if options[:replace]
57
58
 
58
59
  item_storage = item.make_item_storage(storage)
59
- item.copy_item_storage(local_path, storage, item_storage)
60
+ item.copy_item_storage(local_path, storage, item_storage, options[:remove_local])
60
61
  end
61
62
 
62
63
  return item
@@ -72,12 +73,12 @@ module FC
72
73
  item_storage
73
74
  end
74
75
 
75
- def copy_item_storage(src, storage, item_storage)
76
+ def copy_item_storage(src, storage, item_storage, remove_local = false)
76
77
  begin
77
78
  if src.instance_of?(FC::Storage)
78
79
  src.copy_to_local(name, "#{storage.path}#{name}")
79
80
  else
80
- storage.copy_path(src, name)
81
+ storage.copy_path(src, name, remove_local)
81
82
  end
82
83
  md5_on_storage = storage.md5_sum(name)
83
84
  rescue Exception => e
@@ -98,6 +99,7 @@ module FC
98
99
  item_storage.status = 'ready'
99
100
  item_storage.save
100
101
  reload
102
+ File.delete(src) if remove_local && !src.instance_of?(FC::Storage) && File.exists?(src)
101
103
  end
102
104
  end
103
105
  end
@@ -38,12 +38,14 @@ module FC
38
38
  # get available storage for create by size and local item path
39
39
  def get_proper_storage_for_create(size, local_path = nil)
40
40
  storages = get_proper_storages_for_create(size)
41
+ dev = File.stat(local_path).dev if local_path
42
+
41
43
  # sort by current_host and free size
42
44
  storages.sort do |a, b|
43
45
  if FC::Storage.curr_host == a.host && FC::Storage.curr_host == b.host
44
- if local_path && local_path.index(a.path) == 0
46
+ if local_path && dev == File.stat(a.path).dev
45
47
  1
46
- elsif local_path && local_path.index(b.path) == 0
48
+ elsif local_path && dev == File.stat(b.path).dev
47
49
  -1
48
50
  else
49
51
  a.free_rate <=> b.free_rate
@@ -63,16 +63,17 @@ module FC
63
63
  end
64
64
 
65
65
  # copy local_path to storage
66
- def copy_path(local_path, file_name)
66
+ def copy_path(local_path, file_name, try_move = false)
67
67
  dst_path = "#{self.path}#{file_name}"
68
68
 
69
69
  cmd = "rm -rf #{dst_path.shellescape}; mkdir -p #{File.dirname(dst_path).shellescape}"
70
70
  cmd = self.class.curr_host == host ? cmd : "ssh -oBatchMode=yes -oStrictHostKeyChecking=no #{self.host} \"#{cmd}\""
71
71
  r = `#{cmd} 2>&1`
72
72
  raise r if $?.exitstatus != 0
73
-
73
+
74
+ op = try_move && self.class.curr_host == host && File.stat(local_path).dev == File.stat(File.dirname(dst_path)).dev ? 'mv' : 'cp -r'
74
75
  cmd = self.class.curr_host == host ?
75
- "cp -r #{local_path.shellescape} #{dst_path.shellescape}" :
76
+ "#{op} #{local_path.shellescape} #{dst_path.shellescape}" :
76
77
  "scp -r -oBatchMode=yes -oStrictHostKeyChecking=no #{local_path.shellescape} #{self.host}:\"#{dst_path.shellescape}\""
77
78
  r = `#{cmd} 2>&1`
78
79
  raise r if $?.exitstatus != 0
@@ -1,3 +1,3 @@
1
1
  module FC
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -122,4 +122,16 @@ class FunctionalTest < Test::Unit::TestCase
122
122
  `cp #{@@test_file_path.shellescape} #{tmp_dir_path.shellescape}`
123
123
  assert_nothing_raised { FC::Item.create_from_local(tmp_dir_path, '/inplace test dir/', @@policies[0]) }
124
124
  end
125
+
126
+ should "item create_from_local with move and delete" do
127
+ tmp_file_path = "/tmp/fc test file for delete"
128
+ `cp #{@@test_file_path.shellescape} #{tmp_file_path.shellescape}`
129
+ File.stubs(:delete).never
130
+ assert_nothing_raised { @item = FC::Item.create_from_local(tmp_file_path, '/bla/bla/test6', @@policies[0], {:remove_local => true}) }
131
+ assert_kind_of FC::Item, @item
132
+ assert_equal `du -sb #{@@test_file_path.shellescape} 2>&1`.to_i, @item.size
133
+ assert_equal 'ready', @item.status
134
+ assert_equal false, File.exists?(tmp_file_path)
135
+ File.unstub(:delete)
136
+ end
125
137
  end
@@ -58,16 +58,20 @@ class PolicyTest < Test::Unit::TestCase
58
58
  FC::Policy.storages_cache_time = 0
59
59
  @@storages.each {|storage| storage.update_check_time}
60
60
  FC::Storage.stubs(:curr_host).returns('rec2')
61
- assert_equal 'rec2-sdb', @@policy.get_proper_storage_for_create(9, '/tmp/host2-sdb/test').name, 'current host, local path match'
61
+ File.stubs(:stat).with('test-rec2-sdb').returns(OpenStruct.new :dev => 10)
62
+ File.stubs(:stat).with('/tmp/host2-sdb/').returns(OpenStruct.new :dev => 10)
63
+ File.stubs(:stat).with{|s| s != 'test-rec2-sdb' && s != '/tmp/host2-sdb/'}.returns(OpenStruct.new :dev => 0)
64
+ assert_equal 'rec2-sdb', @@policy.get_proper_storage_for_create(9, 'test-rec2-sdb').name, 'current host, dev match'
62
65
  @@storages[3].check_time = 0;
63
66
  @@storages[3].save
64
- assert_equal 'rec2-sdc', @@policy.get_proper_storage_for_create(9, '/tmp/host2-sdb/test').name, 'current host, most free storage'
67
+ assert_equal 'rec2-sdc', @@policy.get_proper_storage_for_create(9, 'test-rec2-sdb').name, 'current host, most free storage'
65
68
  FC::Storage.stubs(:curr_host).returns('rec3')
66
69
  @@storages[5].check_time = 0;
67
70
  @@storages[5].save
68
- assert_equal 'rec3-sdb', @@policy.get_proper_storage_for_create(9, '/tmp/host3-sdc/test').name, 'current host, single storage'
71
+ assert_equal 'rec3-sdb', @@policy.get_proper_storage_for_create(9, 'test-rec2-sdb').name, 'current host, single storage'
69
72
  FC::Storage.stubs(:curr_host).returns('rec5')
70
- assert_equal 'rec1-sda', @@policy.get_proper_storage_for_create(9, '/tmp/host3-sdc/test').name, 'not current host, most free storage'
71
- assert_equal 'rec2-sdc', @@policy.get_proper_storage_for_create(10, '/tmp/host3-sdc/test').name, 'not current host, big file, most free storage with free space'
73
+ assert_equal 'rec1-sda', @@policy.get_proper_storage_for_create(9, 'test-rec2-sdb').name, 'not current host, most free storage'
74
+ assert_equal 'rec2-sdc', @@policy.get_proper_storage_for_create(10, 'test-rec2-sdb').name, 'not current host, big file, most free storage with free space'
75
+ File.unstub(:stat)
72
76
  end
73
77
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filecluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
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: 2014-11-29 00:00:00.000000000 Z
12
+ date: 2014-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mysql2
@@ -181,7 +181,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
181
  version: '0'
182
182
  segments:
183
183
  - 0
184
- hash: -1129513891376945174
184
+ hash: 635343696830163722
185
185
  required_rubygems_version: !ruby/object:Gem::Requirement
186
186
  none: false
187
187
  requirements:
@@ -190,7 +190,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
190
  version: '0'
191
191
  segments:
192
192
  - 0
193
- hash: -1129513891376945174
193
+ hash: 635343696830163722
194
194
  requirements: []
195
195
  rubyforge_project:
196
196
  rubygems_version: 1.8.24