filecluster 0.0.8 → 0.0.9
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/README.md +21 -4
- data/TODO +3 -0
- data/bin/fc-manage +11 -8
- data/lib/daemon/global_daemon_thread.rb +5 -5
- data/lib/fc/db.rb +19 -8
- data/lib/fc/item.rb +2 -2
- data/lib/fc/policy.rb +27 -8
- data/lib/fc/storage.rb +25 -18
- data/lib/fc/version.rb +1 -1
- data/lib/manage/policies.rb +69 -19
- data/lib/manage/storages.rb +79 -12
- data/lib/utils.rb +2 -2
- data/test/daemon_test.rb +9 -9
- data/test/db_test.rb +25 -12
- data/test/functional_test.rb +7 -13
- data/test/policy_test.rb +55 -16
- data/test/storage_test.rb +0 -1
- metadata +4 -4
data/README.md
CHANGED
@@ -1,12 +1,21 @@
|
|
1
|
-
#
|
1
|
+
# FileCluster
|
2
|
+
|
3
|
+
A set of scripts to manage files on multiple dc/host/drive.
|
4
|
+
|
5
|
+
Item (storage unit)- file or folder.
|
6
|
+
Storage - folder, usually separate drive.
|
7
|
+
Policy - rule for selecting storage to store the item and сreate copies.
|
8
|
+
|
9
|
+
Daemon monitors the availability of each storage and copy files between them.
|
10
|
+
|
11
|
+
If the storage is not available or ended the available space is used another available storage according to the policy.
|
2
12
|
|
3
|
-
TODO: Write a gem description
|
4
13
|
|
5
14
|
## Installation
|
6
15
|
|
7
16
|
Add this line to your application's Gemfile:
|
8
17
|
|
9
|
-
gem '
|
18
|
+
gem 'filecluster'
|
10
19
|
|
11
20
|
And then execute:
|
12
21
|
|
@@ -14,7 +23,15 @@ And then execute:
|
|
14
23
|
|
15
24
|
Or install it yourself as:
|
16
25
|
|
17
|
-
$ gem install
|
26
|
+
$ gem install filecluster
|
27
|
+
|
28
|
+
## Create policy
|
29
|
+
|
30
|
+
Selecting available storage to store item by policy.create_storages (from left to tight).
|
31
|
+
|
32
|
+
## Copy policy
|
33
|
+
|
34
|
+
Selecting available storage to copy item by policy.copy_storages (from left to tight) with the nearest copy_id.
|
18
35
|
|
19
36
|
## Usage
|
20
37
|
|
data/TODO
CHANGED
data/bin/fc-manage
CHANGED
@@ -18,19 +18,22 @@ commands_help = {
|
|
18
18
|
'show list and manage storages',
|
19
19
|
%q{Usage: fc-manage [options] storages <command>
|
20
20
|
Command:
|
21
|
-
list
|
22
|
-
show <name>
|
23
|
-
add
|
24
|
-
rm <name>
|
21
|
+
list show all stotages for all hosts
|
22
|
+
show <name> show full info for storage
|
23
|
+
add add new storage
|
24
|
+
rm <name> delete storage
|
25
|
+
change <name> change storage attributes
|
26
|
+
update_size <name> update storage size
|
25
27
|
}],
|
26
28
|
'policies' => [
|
27
29
|
'show list and manage plicies',
|
28
30
|
%q{Usage: fc-manage [options] plicies <command>
|
29
31
|
Command:
|
30
|
-
list
|
31
|
-
show <id>
|
32
|
-
add
|
33
|
-
rm <id>
|
32
|
+
list show all plicies
|
33
|
+
show <id/name> show full info for policy
|
34
|
+
add add new policy
|
35
|
+
rm <id/name> delete policy
|
36
|
+
change <id/name> change policy attributes
|
34
37
|
}],
|
35
38
|
'show' => [
|
36
39
|
'show variable',
|
@@ -32,13 +32,12 @@ class GlobalDaemonThread < BaseThread
|
|
32
32
|
# policies.get_storages => all_policies.select
|
33
33
|
all_policies.each do |policy|
|
34
34
|
metaclass = class << policy; self; end
|
35
|
-
metaclass.send(:define_method, :
|
36
|
-
|
37
|
-
all_storages.select{|storage| policy_storages.member?(storage.name)}
|
35
|
+
metaclass.send(:define_method, :get_copy_storages) do
|
36
|
+
@copy_storages_cache ||= self.copy_storages.split(',').map{|storage_name| all_storages.detect{|s| storage_name == s.name} }
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
|
-
sql = "SELECT i.id as item_id, i.size, i.copies as item_copies, GROUP_CONCAT(ist.storage_name) as storages, p.id as policy_id, p.copies as policy_copies "+
|
40
|
+
sql = "SELECT i.id as item_id, i.size, i.copies as item_copies, GROUP_CONCAT(ist.storage_name ORDER BY ist.id) as storages, p.id as policy_id, p.copies as policy_copies "+
|
42
41
|
"FROM #{FC::Item.table_name} as i, #{FC::Policy.table_name} as p, #{FC::ItemStorage.table_name} as ist WHERE "+
|
43
42
|
"i.policy_id = p.id AND ist.item_id = i.id AND i.copies > 0 AND i.copies < p.copies AND i.status = 'ready' AND ist.status <> 'delete' GROUP BY i.id LIMIT 1000"
|
44
43
|
r = FC::DB.connect.query(sql)
|
@@ -50,8 +49,9 @@ class GlobalDaemonThread < BaseThread
|
|
50
49
|
elsif item_storages.size >= row['policy_copies']
|
51
50
|
$log.warn("GlobalDaemonThread: ItemStorage count >= policy.copies for item #{row['item_id']}")
|
52
51
|
else
|
52
|
+
src_storage = all_storages.detect{|s| item_storages.first == s.name}
|
53
53
|
policy = all_policies.detect{|p| row['policy_id'] == p.id}
|
54
|
-
storage = policy.
|
54
|
+
storage = policy.get_proper_storage_for_copy(row['size'], src_storage.copy_id, item_storages) if src_storage && policy
|
55
55
|
error 'No available storage', :item_id => row['item_id'] unless storage
|
56
56
|
FC::Item.new(:id => row['item_id']).make_item_storage(storage, 'copy')
|
57
57
|
end
|
data/lib/fc/db.rb
CHANGED
@@ -71,14 +71,21 @@ module FC
|
|
71
71
|
size bigint NOT NULL DEFAULT 0,
|
72
72
|
size_limit bigint NOT NULL DEFAULT 0,
|
73
73
|
check_time int DEFAULT NULL,
|
74
|
+
copy_id int NOT NULL DEFAULT 0,
|
74
75
|
PRIMARY KEY (id), UNIQUE KEY (name), KEY (host)
|
75
76
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
|
76
77
|
})
|
77
78
|
proc = %{
|
78
|
-
# update policy.
|
79
|
+
# update policy.create_storages and policy.copy_storages on storage delete and update
|
79
80
|
UPDATE #{@prefix}policies,
|
80
|
-
(SELECT #{@prefix}policies.id, GROUP_CONCAT(name) as storages FROM #{@prefix}policies LEFT JOIN #{@prefix}storages ON
|
81
|
-
|
81
|
+
(SELECT #{@prefix}policies.id, GROUP_CONCAT(#{@prefix}storages.name ORDER BY FIND_IN_SET(#{@prefix}storages.name, create_storages)) as storages FROM #{@prefix}policies LEFT JOIN #{@prefix}storages ON
|
82
|
+
FIND_IN_SET(#{@prefix}storages.name, create_storages) GROUP BY #{@prefix}policies.id) as policy_create,
|
83
|
+
(SELECT #{@prefix}policies.id, GROUP_CONCAT(#{@prefix}storages.name ORDER BY FIND_IN_SET(#{@prefix}storages.name, copy_storages)) as storages FROM #{@prefix}policies LEFT JOIN #{@prefix}storages ON
|
84
|
+
FIND_IN_SET(#{@prefix}storages.name, copy_storages) GROUP BY #{@prefix}policies.id) as policy_copy
|
85
|
+
SET
|
86
|
+
#{@prefix}policies.create_storages = policy_create.storages,
|
87
|
+
#{@prefix}policies.copy_storages = policy_copy.storages
|
88
|
+
WHERE policy_create.id = #{@prefix}policies.id AND policy_copy.id = #{@prefix}policies.id;
|
82
89
|
}
|
83
90
|
proc_update = %{
|
84
91
|
IF OLD.name <> NEW.name THEN
|
@@ -91,15 +98,19 @@ module FC
|
|
91
98
|
FC::DB.connect.query(%{
|
92
99
|
CREATE TABLE #{@prefix}policies (
|
93
100
|
id int NOT NULL AUTO_INCREMENT,
|
94
|
-
|
101
|
+
name varchar(255) NOT NULL DEFAULT '',
|
102
|
+
create_storages text NOT NULL DEFAULT '',
|
103
|
+
copy_storages text NOT NULL DEFAULT '',
|
95
104
|
copies int NOT NULL DEFAULT 0,
|
96
|
-
PRIMARY KEY (id)
|
105
|
+
PRIMARY KEY (id), UNIQUE KEY (name)
|
97
106
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
|
98
107
|
})
|
99
108
|
proc = %{
|
100
|
-
# update policy.
|
101
|
-
SELECT GROUP_CONCAT(name) INTO @
|
102
|
-
|
109
|
+
# update policy.create_storages and policy.copy_storages on policy change - guarantee valid policy.storages
|
110
|
+
SELECT GROUP_CONCAT(name ORDER BY FIND_IN_SET(name, NEW.create_storages)) INTO @create_storages_list FROM #{@prefix}storages WHERE FIND_IN_SET(name, NEW.create_storages);
|
111
|
+
SELECT GROUP_CONCAT(name ORDER BY FIND_IN_SET(name, NEW.copy_storages)) INTO @copy_storages_list FROM #{@prefix}storages WHERE FIND_IN_SET(name, NEW.copy_storages);
|
112
|
+
SET NEW.create_storages = @create_storages_list;
|
113
|
+
SET NEW.copy_storages = @copy_storages_list;
|
103
114
|
}
|
104
115
|
FC::DB.connect.query("CREATE TRIGGER fc_policies_before_insert BEFORE INSERT on #{@prefix}policies FOR EACH ROW BEGIN #{proc} END")
|
105
116
|
FC::DB.connect.query("CREATE TRIGGER fc_policies_before_update BEFORE UPDATE on #{@prefix}policies FOR EACH ROW BEGIN #{proc} END")
|
data/lib/fc/item.rb
CHANGED
@@ -23,7 +23,7 @@ module FC
|
|
23
23
|
raise 'Zero size path' if item_params[:size] == 0
|
24
24
|
|
25
25
|
if local_path.include?(item_name)
|
26
|
-
storage = policy.
|
26
|
+
storage = policy.get_create_storages.detect{|s| local_path.index(s.path) == 0 && local_path.sub(s.path, '') == item_params[:name]}
|
27
27
|
FC::Error.raise "local_path #{local_path} is not valid path for policy ##{policy.id}" unless storage
|
28
28
|
end
|
29
29
|
|
@@ -47,7 +47,7 @@ module FC
|
|
47
47
|
item_storage = item.make_item_storage(storage, 'ready')
|
48
48
|
item.reload
|
49
49
|
else
|
50
|
-
storage = policy.
|
50
|
+
storage = policy.get_proper_storage_for_create(item.size)
|
51
51
|
FC::Error.raise 'No available storage', :item_id => item.id unless storage
|
52
52
|
item_storage = item.make_item_storage(storage)
|
53
53
|
item.copy_item_storage(local_path, storage, item_storage)
|
data/lib/fc/policy.rb
CHANGED
@@ -2,24 +2,43 @@
|
|
2
2
|
|
3
3
|
module FC
|
4
4
|
class Policy < DbBase
|
5
|
-
set_table :policies, '
|
5
|
+
set_table :policies, 'name, create_storages, copy_storages, copies'
|
6
6
|
|
7
7
|
class << self
|
8
8
|
attr_accessor :storages_cache_time
|
9
9
|
end
|
10
10
|
@storages_cache_time = 20 # ttl for storages cache
|
11
11
|
|
12
|
-
def
|
13
|
-
return @
|
14
|
-
@
|
15
|
-
|
12
|
+
def get_create_storages
|
13
|
+
return @create_storages_cache if @create_storages_cache && Time.new.to_i - @get_create_storages_time.to_i < self.class.storages_cache_time
|
14
|
+
@get_create_storages_time = Time.new.to_i
|
15
|
+
names = create_storages.split(',').map{|s| "'#{s}'"}.join(',')
|
16
|
+
@create_storages_cache = FC::Storage.where("name IN (#{names}) ORDER BY FIELD(name, #{names})")
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def get_copy_storages
|
20
|
+
return @copy_storages_cache if @copy_storages_cache && Time.new.to_i - @get_copy_storages_time.to_i < self.class.storages_cache_time
|
21
|
+
@get_copy_storages_time = Time.new.to_i
|
22
|
+
names = copy_storages.split(',').map{|s| "'#{s}'"}.join(',')
|
23
|
+
@copy_storages_cache = FC::Storage.where("name IN (#{names}) ORDER BY FIELD(name, #{names})")
|
24
|
+
end
|
25
|
+
|
26
|
+
# get available storage for create by size
|
27
|
+
def get_proper_storage_for_create(size, exclude = [])
|
28
|
+
get_create_storages.detect do |storage|
|
29
|
+
!exclude.include?(storage.name) && storage.up? && storage.size + size < storage.size_limit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# get available storage for copy by copy_id and size
|
34
|
+
def get_proper_storage_for_copy(size, copy_id = nil, exclude = [])
|
35
|
+
storages = get_copy_storages.select do |storage|
|
21
36
|
!exclude.include?(storage.name) && storage.up? && storage.size + size < storage.size_limit
|
22
37
|
end
|
38
|
+
storage = storages.detect{|s| copy_id.to_i == s.copy_id.to_i}
|
39
|
+
storage = storages.detect{|s| copy_id.to_i < s.copy_id.to_i} unless storage
|
40
|
+
storage = storages.first unless storage
|
41
|
+
storage
|
23
42
|
end
|
24
43
|
end
|
25
44
|
end
|
data/lib/fc/storage.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module FC
|
4
4
|
class Storage < DbBase
|
5
|
-
set_table :storages, 'name, host, path, url, size, size_limit, check_time'
|
5
|
+
set_table :storages, 'name, host, path, url, size, size_limit, check_time, copy_id'
|
6
6
|
|
7
7
|
class << self
|
8
8
|
attr_accessor :check_time_limit
|
@@ -16,7 +16,9 @@ module FC
|
|
16
16
|
def initialize(params = {})
|
17
17
|
path = (params['path'] || params[:path])
|
18
18
|
if path && !path.to_s.empty?
|
19
|
+
path += '/' unless path[-1] == '/'
|
19
20
|
raise "Storage path must be like '/bla/bla../'" unless path.match(/^\/.*\/$/)
|
21
|
+
params['path'] = params[:path] = path
|
20
22
|
end
|
21
23
|
super params
|
22
24
|
end
|
@@ -31,47 +33,52 @@ module FC
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def up?
|
34
|
-
|
36
|
+
check_time_delay < self.class.check_time_limit
|
35
37
|
end
|
36
38
|
|
37
39
|
# copy local_path to storage
|
38
40
|
def copy_path(local_path, file_name)
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
dst_path = "#{self.path}#{file_name}"
|
42
|
+
|
43
|
+
cmd = self.class.curr_host == host ? "mkdir -p #{File.dirname(dst_path)}" : "ssh -oBatchMode=yes #{self.host} 'mkdir -p #{File.dirname(dst_path)}'"
|
44
|
+
r = `#{cmd} 2>&1`
|
45
|
+
raise r if $?.exitstatus != 0
|
46
|
+
|
47
|
+
cmd = self.class.curr_host == host ? "cp -r #{local_path} #{dst_path}" : "scp -rB #{local_path} #{self.host}:#{dst_path}"
|
42
48
|
r = `#{cmd} 2>&1`
|
43
49
|
raise r if $?.exitstatus != 0
|
44
50
|
end
|
45
51
|
|
46
52
|
# copy object to local_path
|
47
53
|
def copy_to_local(file_name, local_path)
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
src_path = "#{self.path}#{file_name}"
|
55
|
+
|
56
|
+
cmd = self.class.curr_host == host ? "mkdir -p #{File.dirname(local_path)}" : "ssh -oBatchMode=yes #{self.host} 'mkdir -p #{File.dirname(local_path)}'"
|
57
|
+
r = `#{cmd} 2>&1`
|
58
|
+
raise r if $?.exitstatus != 0
|
59
|
+
|
60
|
+
cmd = self.class.curr_host == host ? "cp -r #{src_path} #{local_path}" : "scp -rB #{self.host}:#{src_path} #{local_path}"
|
51
61
|
r = `#{cmd} 2>&1`
|
52
62
|
raise r if $?.exitstatus != 0
|
53
63
|
end
|
54
64
|
|
55
65
|
# delete object from storage
|
56
66
|
def delete_file(file_name)
|
57
|
-
|
58
|
-
|
59
|
-
"ssh -oBatchMode=yes #{self.host} 'rm -rf #{self.path}#{file_name}'"
|
67
|
+
dst_path = "#{self.path}#{file_name}"
|
68
|
+
cmd = self.class.curr_host == host ? "rm -rf #{dst_path}" : "ssh -oBatchMode=yes #{self.host} 'rm -rf #{dst_path}'"
|
60
69
|
r = `#{cmd} 2>&1`
|
61
70
|
raise r if $?.exitstatus != 0
|
62
71
|
|
63
|
-
cmd = self.class.curr_host == host ?
|
64
|
-
"ls -la #{self.path}#{file_name}" :
|
65
|
-
"ssh -oBatchMode=yes #{self.host} 'ls -la #{self.path}#{file_name}'"
|
72
|
+
cmd = self.class.curr_host == host ? "ls -la #{dst_path}" : "ssh -oBatchMode=yes #{self.host} 'ls -la #{dst_path}'"
|
66
73
|
r = `#{cmd} 2>/dev/null`
|
67
|
-
raise "Path #{
|
74
|
+
raise "Path #{dst_path} not deleted" unless r.empty?
|
68
75
|
end
|
69
76
|
|
70
77
|
# return object size on storage
|
71
78
|
def file_size(file_name)
|
72
|
-
|
73
|
-
|
74
|
-
|
79
|
+
dst_path = "#{self.path}#{file_name}"
|
80
|
+
|
81
|
+
cmd = self.class.curr_host == host ? "du -sb #{dst_path}" : "ssh -oBatchMode=yes #{self.host} 'du -sb #{dst_path}'"
|
75
82
|
r = `#{cmd} 2>&1`
|
76
83
|
raise r if $?.exitstatus != 0
|
77
84
|
r.to_i
|
data/lib/fc/version.rb
CHANGED
data/lib/manage/policies.rb
CHANGED
@@ -4,39 +4,46 @@ def policies_list
|
|
4
4
|
puts "No storages."
|
5
5
|
else
|
6
6
|
policies.each do |policy|
|
7
|
-
puts "##{policy.id} storages: #{policy.storages}, copies: #{policy.copies}"
|
7
|
+
puts "##{policy.id} #{policy.name}, create storages: #{policy.create_storages}, copy storages: #{policy.copy_storages}, copies: #{policy.copies}"
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
def policies_show
|
13
|
-
|
14
|
-
policy = FC::Policy.where('id = ?', id).first
|
15
|
-
if !policy
|
16
|
-
puts "Policy ##{id} not found."
|
17
|
-
else
|
13
|
+
if policy = find_policy
|
18
14
|
count = FC::DB.connect.query("SELECT count(*) as cnt FROM #{FC::Item.table_name} WHERE policy_id = #{policy.id}").first['cnt']
|
19
15
|
puts %Q{Policy
|
20
|
-
ID:
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
ID: #{policy.id}
|
17
|
+
Name: #{policy.name}
|
18
|
+
Create storages: #{policy.create_storages}
|
19
|
+
Copy storages: #{policy.copy_storages}
|
20
|
+
Copies: #{policy.copies}
|
21
|
+
Items: #{count}}
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
25
|
def policies_add
|
28
26
|
puts "Add Policy"
|
29
|
-
|
27
|
+
name = stdin_read_val('Name')
|
28
|
+
create_storages = stdin_read_val('Create storages')
|
29
|
+
copy_storages = stdin_read_val('Copy storages')
|
30
30
|
copies = stdin_read_val('Copies').to_i
|
31
|
+
|
32
|
+
storages = FC::Storage.where.map(&:name)
|
33
|
+
create_storages = create_storages.split(',').select{|s| storages.member?(s.strip)}.join(',').strip
|
34
|
+
copy_storages = copy_storages.split(',').select{|s| storages.member?(s.strip)}.join(',').strip
|
35
|
+
|
31
36
|
begin
|
32
|
-
policy = FC::Policy.new(:
|
37
|
+
policy = FC::Policy.new(:name => name, :create_storages => create_storages, :copy_storages => copy_storages, :copies => copies)
|
33
38
|
rescue Exception => e
|
34
39
|
puts "Error: #{e.message}"
|
35
40
|
exit
|
36
41
|
end
|
37
42
|
puts %Q{\nPolicy
|
38
|
-
|
39
|
-
|
43
|
+
Name: #{name}
|
44
|
+
Create storages: #{create_storages}
|
45
|
+
Copy storages: #{copy_storages}
|
46
|
+
Copies: #{copies}}
|
40
47
|
s = Readline.readline("Continue? (y/n) ", false).strip.downcase
|
41
48
|
puts ""
|
42
49
|
if s == "y" || s == "yes"
|
@@ -53,11 +60,7 @@ def policies_add
|
|
53
60
|
end
|
54
61
|
|
55
62
|
def policies_rm
|
56
|
-
|
57
|
-
policy = FC::Policy.where('id = ?', id).first
|
58
|
-
if !policy
|
59
|
-
puts "Policy ##{id} not found."
|
60
|
-
else
|
63
|
+
if policy = find_policy
|
61
64
|
s = Readline.readline("Continue? (y/n) ", false).strip.downcase
|
62
65
|
puts ""
|
63
66
|
if s == "y" || s == "yes"
|
@@ -68,3 +71,50 @@ def policies_rm
|
|
68
71
|
end
|
69
72
|
end
|
70
73
|
end
|
74
|
+
|
75
|
+
def policies_change
|
76
|
+
if policy = find_policy
|
77
|
+
puts "Change policy ##{policy.id} #{policy.name}"
|
78
|
+
name = stdin_read_val("Name (now #{policy.name})", true)
|
79
|
+
create_storages = stdin_read_val("Create storages (now #{policy.create_storages})", true)
|
80
|
+
copy_storages = stdin_read_val("Copy storages (now #{policy.copy_storages})", true)
|
81
|
+
copies = stdin_read_val("Copies (now #{policy.copies})", true)
|
82
|
+
|
83
|
+
storages = FC::Storage.where.map(&:name)
|
84
|
+
create_storages = create_storages.split(',').select{|s| storages.member?(s.strip)}.join(',').strip unless create_storages.empty?
|
85
|
+
copy_storages = copy_storages.split(',').select{|s| storages.member?(s.strip)}.join(',').strip unless copy_storages.empty?
|
86
|
+
|
87
|
+
policy.name = name unless name.empty?
|
88
|
+
policy.create_storages = name unless create_storages.empty?
|
89
|
+
policy.copy_storages = name unless copy_storages.empty?
|
90
|
+
policy.copies = copies.to_i unless copies.empty?
|
91
|
+
|
92
|
+
puts %Q{\nStorage
|
93
|
+
Name: #{policy.name}
|
94
|
+
Create storages: #{policy.create_storages}
|
95
|
+
Copy storages: #{policy.copy_storages}
|
96
|
+
Copies: #{policy.copies}}
|
97
|
+
s = Readline.readline("Continue? (y/n) ", false).strip.downcase
|
98
|
+
puts ""
|
99
|
+
if s == "y" || s == "yes"
|
100
|
+
begin
|
101
|
+
policy.save
|
102
|
+
rescue Exception => e
|
103
|
+
puts "Error: #{e.message}"
|
104
|
+
exit
|
105
|
+
end
|
106
|
+
puts "ok"
|
107
|
+
else
|
108
|
+
puts "Canceled."
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def find_policy
|
116
|
+
policy = FC::Policy.where('id = ?', ARGV[2]).first
|
117
|
+
policy = FC::Policy.where('name = ?', ARGV[2]).first unless policy
|
118
|
+
puts "Policy #{ARGV[2]} not found." unless policy
|
119
|
+
policy
|
120
|
+
end
|
data/lib/manage/storages.rb
CHANGED
@@ -13,11 +13,7 @@ def storages_list
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def storages_show
|
16
|
-
|
17
|
-
storage = FC::Storage.where('name = ?', name).first
|
18
|
-
if !storage
|
19
|
-
puts "Storage #{name} not found."
|
20
|
-
else
|
16
|
+
if storage = find_storage
|
21
17
|
count = FC::DB.connect.query("SELECT count(*) as cnt FROM #{FC::ItemStorage.table_name} WHERE storage_name='#{Mysql2::Client.escape(storage.name)}'").first['cnt']
|
22
18
|
puts %Q{Storage
|
23
19
|
Name: #{storage.name}
|
@@ -26,6 +22,7 @@ def storages_show
|
|
26
22
|
Url: #{storage.url}
|
27
23
|
Size: #{size_to_human storage.size}
|
28
24
|
Size limit: #{size_to_human storage.size_limit}
|
25
|
+
Copy id: #{storage.copy_id}
|
29
26
|
Check time: #{storage.check_time ? "#{Time.at(storage.check_time)} (#{storage.check_time_delay} seconds ago)" : ''}
|
30
27
|
Status: #{storage.up? ? colorize_string('UP', :green) : colorize_string('DOWN', :red)}
|
31
28
|
Items storages: #{count}}
|
@@ -39,8 +36,11 @@ def storages_add
|
|
39
36
|
path = stdin_read_val('Path')
|
40
37
|
url = stdin_read_val('Url')
|
41
38
|
size_limit = human_to_size stdin_read_val('Size limit') {|val| "Size limit not is valid size." unless human_to_size(val)}
|
39
|
+
copy_id = stdin_read_val('Copy id').to_i
|
42
40
|
begin
|
43
|
-
|
41
|
+
path = path +'/' unless path[-1] == '/'
|
42
|
+
path = '/' + path unless path[0] == '/'
|
43
|
+
storage = FC::Storage.new(:name => name, :host => host, :path => path, :url => url, :size_limit => size_limit, :copy_id => copy_id)
|
44
44
|
print "Calc current size.. "
|
45
45
|
size = storage.file_size('')
|
46
46
|
puts "ok"
|
@@ -54,7 +54,8 @@ def storages_add
|
|
54
54
|
Path: #{path}
|
55
55
|
Url: #{url}
|
56
56
|
Size: #{size_to_human size}
|
57
|
-
Size limit: #{size_to_human size_limit}
|
57
|
+
Size limit: #{size_to_human size_limit}
|
58
|
+
Copy id: #{copy_id}}
|
58
59
|
s = Readline.readline("Continue? (y/n) ", false).strip.downcase
|
59
60
|
puts ""
|
60
61
|
if s == "y" || s == "yes"
|
@@ -72,11 +73,7 @@ def storages_add
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def storages_rm
|
75
|
-
|
76
|
-
storage = FC::Storage.where('name = ?', name).first
|
77
|
-
if !storage
|
78
|
-
puts "Storage #{name} not found."
|
79
|
-
else
|
76
|
+
if storage = find_storage
|
80
77
|
s = Readline.readline("Continue? (y/n) ", false).strip.downcase
|
81
78
|
puts ""
|
82
79
|
if s == "y" || s == "yes"
|
@@ -87,3 +84,73 @@ def storages_rm
|
|
87
84
|
end
|
88
85
|
end
|
89
86
|
end
|
87
|
+
|
88
|
+
def storages_update_size
|
89
|
+
if storage = find_storage
|
90
|
+
print "Calc current size.. "
|
91
|
+
size = storage.file_size('')
|
92
|
+
storage.size = size
|
93
|
+
begin
|
94
|
+
storage.save
|
95
|
+
rescue Exception => e
|
96
|
+
puts "Error: #{e.message}"
|
97
|
+
exit
|
98
|
+
end
|
99
|
+
puts "ok"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def storages_change
|
104
|
+
if storage = find_storage
|
105
|
+
puts "Change storage #{storage.name}"
|
106
|
+
host = stdin_read_val("Host (now #{storage.host})", true)
|
107
|
+
path = stdin_read_val("Path (now #{storage.path})", true)
|
108
|
+
url = stdin_read_val("Url (now #{storage.url})", true)
|
109
|
+
size_limit = stdin_read_val("Size (now #{size_to_human(storage.size_limit)})", true) {|val| "Size limit not is valid size." if !val.empty? && !human_to_size(val)}
|
110
|
+
copy_id = stdin_read_val("Copy id (now #{storage.copy_id})", true)
|
111
|
+
|
112
|
+
storage.host = host unless host.empty?
|
113
|
+
if !path.empty? && path != storage.path
|
114
|
+
path = path +'/' unless path[-1] == '/'
|
115
|
+
path = '/' + path unless path[0] == '/'
|
116
|
+
storage.path = path
|
117
|
+
print "Calc current size.. "
|
118
|
+
storage.size = storage.file_size('')
|
119
|
+
puts "ok"
|
120
|
+
end
|
121
|
+
storage.url = url unless url.empty?
|
122
|
+
storage.size_limit = human_to_size(size_limit) unless size_limit.empty?
|
123
|
+
storage.copy_id = copy_id.to_i
|
124
|
+
|
125
|
+
puts %Q{\nStorage
|
126
|
+
Name: #{storage.name}
|
127
|
+
Host: #{storage.host}
|
128
|
+
Path: #{storage.path}
|
129
|
+
Url: #{storage.url}
|
130
|
+
Size: #{size_to_human storage.size}
|
131
|
+
Size limit: #{size_to_human storage.size_limit}
|
132
|
+
Copy id: #{copy_id}}
|
133
|
+
s = Readline.readline("Continue? (y/n) ", false).strip.downcase
|
134
|
+
puts ""
|
135
|
+
if s == "y" || s == "yes"
|
136
|
+
begin
|
137
|
+
storage.save
|
138
|
+
rescue Exception => e
|
139
|
+
puts "Error: #{e.message}"
|
140
|
+
exit
|
141
|
+
end
|
142
|
+
puts "ok"
|
143
|
+
else
|
144
|
+
puts "Canceled."
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def find_storage
|
152
|
+
name = ARGV[2]
|
153
|
+
storage = FC::Storage.where('name = ?', name).first
|
154
|
+
puts "Storage #{name} not found." if !storage
|
155
|
+
storage
|
156
|
+
end
|
data/lib/utils.rb
CHANGED
@@ -40,9 +40,9 @@ def human_to_size(size)
|
|
40
40
|
result.to_i
|
41
41
|
end
|
42
42
|
|
43
|
-
def stdin_read_val(name)
|
43
|
+
def stdin_read_val(name, can_empty = false)
|
44
44
|
while val = Readline.readline("#{name}: ", false).strip.downcase
|
45
|
-
if val.empty?
|
45
|
+
if val.empty? && !can_empty
|
46
46
|
puts "Input non empty #{name}."
|
47
47
|
else
|
48
48
|
if block_given?
|
data/test/daemon_test.rb
CHANGED
@@ -37,12 +37,12 @@ class DaemonTest < Test::Unit::TestCase
|
|
37
37
|
`dd if=/dev/urandom of=#{@@test_file_path} bs=1M count=1 2>&1`
|
38
38
|
|
39
39
|
@@storages = []
|
40
|
-
@@storages << FC::Storage.new(:name => 'host1-sda', :host => 'host1', :path => '/tmp/host1-sda/', :size_limit => 1000000000)
|
41
|
-
@@storages << FC::Storage.new(:name => 'host1-sdb', :host => 'host1', :path => '/tmp/host1-sdb/', :size_limit => 1000000000)
|
42
|
-
@@storages << FC::Storage.new(:name => 'host1-sdc', :host => 'host1', :path => '/tmp/host1-sdc/', :size_limit => 1000000000)
|
40
|
+
@@storages << FC::Storage.new(:name => 'host1-sda', :host => 'host1', :path => '/tmp/host1-sda/', :copy_id => 1, :size_limit => 1000000000)
|
41
|
+
@@storages << FC::Storage.new(:name => 'host1-sdb', :host => 'host1', :path => '/tmp/host1-sdb/', :copy_id => 2, :size_limit => 1000000000)
|
42
|
+
@@storages << FC::Storage.new(:name => 'host1-sdc', :host => 'host1', :path => '/tmp/host1-sdc/', :copy_id => 1, :size_limit => 1000000000)
|
43
43
|
@@storages.each { |storage| storage.save}
|
44
44
|
|
45
|
-
@@policy = FC::Policy.new(:
|
45
|
+
@@policy = FC::Policy.new(:create_storages => 'host1-sda,host1-sdb,host1-sdc', :copy_storages => 'host1-sda,host1-sdb,host1-sdc', :copies => 2, :name => 'policy 1')
|
46
46
|
@@policy.save
|
47
47
|
|
48
48
|
# wait for running fc-daemon
|
@@ -70,9 +70,9 @@ class DaemonTest < Test::Unit::TestCase
|
|
70
70
|
|
71
71
|
FC::Storage.any_instance.stubs(:host).returns('host1')
|
72
72
|
FC::Storage.stubs(:curr_host).returns('host1')
|
73
|
-
assert_nothing_raised { @item1 = FC::Item.create_from_local(@@test_file_path, 'test1', @@policy, {:tag => 'test1'}) }
|
74
|
-
assert_nothing_raised { @item2 = FC::Item.create_from_local(@@test_file_path, 'test2', @@policy, {:tag => 'test2'}) }
|
75
|
-
assert_nothing_raised { @item3 = FC::Item.create_from_local(@@test_file_path, 'test3', @@policy, {:tag => 'test3'}) }
|
73
|
+
assert_nothing_raised { @item1 = FC::Item.create_from_local(@@test_file_path, 'bla/bla/test1', @@policy, {:tag => 'test1'}) }
|
74
|
+
assert_nothing_raised { @item2 = FC::Item.create_from_local(@@test_file_path, 'bla/bla/test2', @@policy, {:tag => 'test2'}) }
|
75
|
+
assert_nothing_raised { @item3 = FC::Item.create_from_local(@@test_file_path, 'bla/bla/test3', @@policy, {:tag => 'test3'}) }
|
76
76
|
|
77
77
|
@@policy.copies = 3
|
78
78
|
@@policy.save
|
@@ -81,7 +81,7 @@ class DaemonTest < Test::Unit::TestCase
|
|
81
81
|
# wait for copy
|
82
82
|
[1, 2, 3].each do |i|
|
83
83
|
['b', 'c'].each do |j|
|
84
|
-
assert_equal `du -b /tmp/host1-sda/test$i 2>&1`.to_i, `du -b /tmp/host$i-sd$j/test$i 2>&1`.to_i
|
84
|
+
assert_equal `du -b /tmp/host1-sda/bla/bla/test$i 2>&1`.to_i, `du -b /tmp/host$i-sd$j/bla/bla/test$i 2>&1`.to_i
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -91,7 +91,7 @@ class DaemonTest < Test::Unit::TestCase
|
|
91
91
|
item_storage.status = 'delete'
|
92
92
|
item_storage.save
|
93
93
|
sleep 2
|
94
|
-
assert_equal 0, `du -b /tmp/host1-sdc/test1 2>&1`.to_i
|
94
|
+
assert_equal 0, `du -b /tmp/host1-sdc/bla/bla/test1 2>&1`.to_i
|
95
95
|
|
96
96
|
assert_equal @@errors_count, FC::Error.where.count, "new errors in errors table"
|
97
97
|
end
|
data/test/db_test.rb
CHANGED
@@ -15,9 +15,9 @@ class DbTest < Test::Unit::TestCase
|
|
15
15
|
@@storages_ids = storages.map{|storage| storage.save; storage.id }
|
16
16
|
|
17
17
|
policies = []
|
18
|
-
policies << FC::Policy.new(:
|
19
|
-
policies << FC::Policy.new(:
|
20
|
-
policies << FC::Policy.new(:
|
18
|
+
policies << FC::Policy.new(:create_storages => 'rec1-sda,rec1-sdd', :copy_storages => 'rec2-sda,rec2-sdd', :copies => 2, :name => 'policy 1')
|
19
|
+
policies << FC::Policy.new(:create_storages => 'rec1-sda,bla,rec2-sdd', :copy_storages => 'rec2-sda,bla,rec1-sdd', :copies => 3, :name => 'policy 2')
|
20
|
+
policies << FC::Policy.new(:create_storages => 'bla,rec1-sda,test', :copy_storages => 'bla,rec2-sda,test', :copies => 4, :name => 'policy 3')
|
21
21
|
@@policies_ids = policies.map{|policy| policy.save; policy.id }
|
22
22
|
|
23
23
|
items = []
|
@@ -75,26 +75,39 @@ class DbTest < Test::Unit::TestCase
|
|
75
75
|
|
76
76
|
should "policies and storages" do
|
77
77
|
assert @policies.count > 0, 'Policies not loaded'
|
78
|
-
assert_equal 'rec1-sda,rec1-sdd', @policies[0].
|
79
|
-
assert_equal 'rec1-sda,rec2-sdd', @policies[1].
|
80
|
-
assert_equal 'rec1-sda', @policies[2].
|
81
|
-
|
78
|
+
assert_equal 'rec1-sda,rec1-sdd', @policies[0].create_storages, "Policy (id=#{@policies[0].id}) incorrect create_storages"
|
79
|
+
assert_equal 'rec1-sda,rec2-sdd', @policies[1].create_storages, "Policy (id=#{@policies[0].id}) incorrect create_storages"
|
80
|
+
assert_equal 'rec1-sda', @policies[2].create_storages, "Policy (id=#{@policies[0].id}) incorrect create_storages"
|
81
|
+
assert_equal 'rec2-sda,rec2-sdd', @policies[0].copy_storages, "Policy (id=#{@policies[0].id}) incorrect copy_storages"
|
82
|
+
assert_equal 'rec2-sda,rec1-sdd', @policies[1].copy_storages, "Policy (id=#{@policies[0].id}) incorrect copy_storages"
|
83
|
+
assert_equal 'rec2-sda', @policies[2].copy_storages, "Policy (id=#{@policies[0].id}) incorrect copy_storages"
|
84
|
+
|
85
|
+
assert_raise(Mysql2::Error, 'Create policy with uniq name') { FC::Policy.new(:create_storages => 'bla,test', :copy_storages => 'rec2-sda', :name => 'policy 1').save }
|
86
|
+
assert_raise(Mysql2::Error, 'Create policy with incorrect create_storages') { FC::Policy.new(:create_storages => 'bla,test', :copy_storages => 'rec2-sda', :name => 'new policy').save }
|
87
|
+
assert_raise(Mysql2::Error, 'Create policy with incorrect copy_storages') { FC::Policy.new(:create_storages => 'rec1-sda', :copy_storages => 'bla,test', :name => 'new policy').save }
|
88
|
+
|
82
89
|
assert_raise(Mysql2::Error, 'Change storage name with linked polices') { @storages[0].name = 'blabla'; @storages[0].save }
|
83
90
|
assert_raise(Mysql2::Error, 'Delete storage name with linked polices') { @storages[0].delete }
|
84
91
|
assert_nothing_raised { @storages[6].name = 'rec2-sdc-new'; @storages[6].save }
|
85
92
|
@storages[3].name = 'rec1-sdd-new' #rec1-sdd
|
86
93
|
@storages[3].save
|
87
94
|
@policies[0].reload
|
88
|
-
|
95
|
+
@policies[1].reload
|
96
|
+
assert_equal 'rec1-sda', @policies[0].create_storages, "Policy (id=#{@policies[0].id}) incorrect create_storages after storage change"
|
97
|
+
assert_equal 'rec2-sda', @policies[1].copy_storages, "Policy (id=#{@policies[1].id}) incorrect copy_storages after storage change"
|
89
98
|
@storages[7].delete #rec2-sdd
|
90
99
|
@@storages_ids.delete(@storages[7].id)
|
100
|
+
@policies[0].reload
|
91
101
|
@policies[1].reload
|
92
|
-
assert_equal 'rec1-sda', @policies[1].
|
93
|
-
@policies[0].
|
102
|
+
assert_equal 'rec1-sda', @policies[1].create_storages, "Policy (id=#{@policies[1].id}) incorrect create_storages after storage delete"
|
103
|
+
assert_equal 'rec2-sda', @policies[0].copy_storages, "Policy (id=#{@policies[0].id}) incorrect copy_storages after storage delete"
|
104
|
+
@policies[0].create_storages = 'rec2-sda,rec1-sda,bla bla'
|
105
|
+
@policies[0].copy_storages = 'rec1-sdb,rec2-sda,bla bla'
|
94
106
|
@policies[0].save
|
95
107
|
@policies[0].reload
|
96
|
-
assert_equal '
|
97
|
-
|
108
|
+
assert_equal 'rec2-sda,rec1-sda', @policies[0].create_storages, "Policy (id=#{@policies[0].id}) incorrect create_storages after change"
|
109
|
+
assert_equal 'rec1-sdb,rec2-sda', @policies[0].copy_storages, "Policy (id=#{@policies[0].id}) incorrect copy_storages after change"
|
110
|
+
assert_raise(Mysql2::Error, 'Save empty policy storage') { @policies[0].create_storages = 'blabla'; @policies[0].save }
|
98
111
|
end
|
99
112
|
|
100
113
|
should "item_storages doubles" do
|
data/test/functional_test.rb
CHANGED
@@ -20,10 +20,10 @@ class FunctionalTest < Test::Unit::TestCase
|
|
20
20
|
@@storages.each { |storage| storage.save}
|
21
21
|
|
22
22
|
@@policies = []
|
23
|
-
@@policies << FC::Policy.new(:
|
24
|
-
@@policies << FC::Policy.new(:
|
25
|
-
@@policies << FC::Policy.new(:
|
26
|
-
@@policies << FC::Policy.new(:
|
23
|
+
@@policies << FC::Policy.new(:create_storages => 'host1-sda,host2-sda', :copy_storages => 'host1-sdb', :copies => 2, :name => 'policy 1')
|
24
|
+
@@policies << FC::Policy.new(:create_storages => 'host1-sdb,host2-sdb', :copy_storages => 'host1-sdb', :copies => 2, :name => 'policy 2')
|
25
|
+
@@policies << FC::Policy.new(:create_storages => 'host3-sda', :copy_storages => 'host1-sdb', :copies => 1, :name => 'policy 3')
|
26
|
+
@@policies << FC::Policy.new(:create_storages => 'host2-sda', :copy_storages => 'host1-sdb', :copies => 1, :name => 'policy 4')
|
27
27
|
@@policies.each { |policy| policy.save}
|
28
28
|
end
|
29
29
|
def shutdown
|
@@ -41,10 +41,10 @@ class FunctionalTest < Test::Unit::TestCase
|
|
41
41
|
end
|
42
42
|
|
43
43
|
should "item create_from_local successful" do
|
44
|
-
assert_nothing_raised { @item = FC::Item.create_from_local(@@test_file_path, 'test1', @@policies[0], {:tag => 'test'}) }
|
44
|
+
assert_nothing_raised { @item = FC::Item.create_from_local(@@test_file_path, '/bla/bla/test1', @@policies[0], {:tag => 'test'}) }
|
45
45
|
assert_kind_of FC::Item, @item
|
46
|
-
assert_equal `du -b /tmp/host1-sda/test1 2>&1`.to_i, `du -b #{@@test_file_path} 2>&1`.to_i
|
47
|
-
assert_equal `du -b /tmp/host1-sda/test1 2>&1`.to_i, @item.size
|
46
|
+
assert_equal `du -b /tmp/host1-sda/bla/bla/test1 2>&1`.to_i, `du -b #{@@test_file_path} 2>&1`.to_i
|
47
|
+
assert_equal `du -b /tmp/host1-sda/bla/bla/test1 2>&1`.to_i, @item.size
|
48
48
|
assert_equal 'ready', @item.status
|
49
49
|
item_storages = @item.get_item_storages
|
50
50
|
assert_equal 1, item_storages.count
|
@@ -53,12 +53,6 @@ class FunctionalTest < Test::Unit::TestCase
|
|
53
53
|
assert_equal 'host1-sda', item_storage.storage_name
|
54
54
|
end
|
55
55
|
|
56
|
-
should "item create_from_local error local path" do
|
57
|
-
errors_count = FC::Error.where.count
|
58
|
-
assert_raise(RuntimeError) { FC::Item.create_from_local(@@test_file_path, 'test2', @@policies[1], {:tag => 'test'}) }
|
59
|
-
assert_equal errors_count+1, FC::Error.where.count, "Error not saved after error local path"
|
60
|
-
end
|
61
|
-
|
62
56
|
should "item create_from_local replace" do
|
63
57
|
@item = FC::Item.new(:name => 'test2', :policy_id => @@policies[0].id)
|
64
58
|
@item.save
|
data/test/policy_test.rb
CHANGED
@@ -4,11 +4,13 @@ class PolicyTest < Test::Unit::TestCase
|
|
4
4
|
class << self
|
5
5
|
def startup
|
6
6
|
@@storages = []
|
7
|
-
@@storages << FC::Storage.new(:name => 'rec1-sda', :host => 'rec1', :size => 0, :size_limit => 10)
|
8
|
-
@@storages << FC::Storage.new(:name => 'rec2-sda', :host => 'rec2', :size => 0, :size_limit => 100)
|
7
|
+
@@storages << FC::Storage.new(:name => 'rec1-sda', :host => 'rec1', :size => 0, :copy_id => 1, :size_limit => 10)
|
8
|
+
@@storages << FC::Storage.new(:name => 'rec2-sda', :host => 'rec2', :size => 0, :copy_id => 2 , :size_limit => 100)
|
9
9
|
@@storages.each {|storage| storage.save}
|
10
|
-
|
11
|
-
@@
|
10
|
+
@@storage3 = FC::Storage.new(:name => 'rec3-sda', :host => 'rec3', :size => 8, :copy_id => 3 , :size_limit => 10)
|
11
|
+
@@storage3.save
|
12
|
+
|
13
|
+
@@policy = FC::Policy.new(:create_storages => 'rec1-sda,rec2-sda', :copy_storages => 'rec1-sda,rec2-sda', :copies => 1, :name => 'policy 1')
|
12
14
|
@@policy.save
|
13
15
|
end
|
14
16
|
def shutdown
|
@@ -17,26 +19,63 @@ class PolicyTest < Test::Unit::TestCase
|
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
|
-
should "
|
22
|
+
should "get_create_storages" do
|
21
23
|
FC::Policy.storages_cache_time = 10
|
22
|
-
assert_same_elements @@storages.map(&:id), @@policy.
|
23
|
-
|
24
|
-
@@policy.storages = 'rec1-sda,rec2-sda,rec2-sdc'
|
24
|
+
assert_same_elements @@storages.map(&:id), @@policy.get_create_storages.map(&:id)
|
25
|
+
@@policy.create_storages = 'rec1-sda,rec2-sda,rec3-sda'
|
25
26
|
@@policy.save
|
26
|
-
assert_equal @@storages.size, @@policy.
|
27
|
+
assert_equal @@storages.size, @@policy.get_create_storages.size
|
27
28
|
FC::Policy.storages_cache_time = 0
|
28
|
-
assert_equal @@storages.size+1, @@policy.
|
29
|
+
assert_equal @@storages.size+1, @@policy.get_create_storages.size
|
29
30
|
end
|
30
31
|
|
31
|
-
should "
|
32
|
+
should "get_copy_storages" do
|
33
|
+
@@policy.copy_storages = 'rec1-sda,rec2-sda'
|
34
|
+
@@policy.save
|
35
|
+
FC::Policy.storages_cache_time = 10
|
36
|
+
assert_same_elements @@storages.map(&:id), @@policy.get_copy_storages.map(&:id)
|
37
|
+
@@policy.copy_storages = 'rec1-sda,rec2-sda,rec3-sda'
|
38
|
+
@@policy.save
|
39
|
+
assert_equal @@storages.size, @@policy.get_copy_storages.size
|
32
40
|
FC::Policy.storages_cache_time = 0
|
33
|
-
|
41
|
+
assert_equal @@storages.size+1, @@policy.get_copy_storages.size
|
42
|
+
end
|
43
|
+
|
44
|
+
should "get_proper_storage_for_create" do
|
45
|
+
@@storages.each {|storage| storage.check_time = 0; storage.save}
|
46
|
+
@@storage3.check_time = 0
|
47
|
+
@@storage3.save
|
48
|
+
FC::Policy.storages_cache_time = 0
|
49
|
+
assert_nil @@policy.get_proper_storage_for_create(1), 'all storages down'
|
34
50
|
@@storages[0].update_check_time
|
35
|
-
assert_equal @@storages[0].id, @@policy.
|
36
|
-
assert_nil @@policy.
|
51
|
+
assert_equal @@storages[0].id, @@policy.get_proper_storage_for_create(5).id, 'first storages up'
|
52
|
+
assert_nil @@policy.get_proper_storage_for_create(20), 'first storage full'
|
37
53
|
@@storages[1].update_check_time
|
38
|
-
assert_equal @@storages[1].id, @@policy.
|
39
|
-
assert_nil @@policy.
|
54
|
+
assert_equal @@storages[1].id, @@policy.get_proper_storage_for_create(20).id, 'second storages up'
|
55
|
+
assert_nil @@policy.get_proper_storage_for_create(1000), 'all storages full'
|
40
56
|
end
|
41
57
|
|
58
|
+
should "get_proper_storage_for_copy" do
|
59
|
+
@@storages.each {|storage| storage.check_time = 0; storage.save}
|
60
|
+
FC::Policy.storages_cache_time = 0
|
61
|
+
assert_nil @@policy.get_proper_storage_for_copy(1), 'all storages down'
|
62
|
+
@@storages[0].update_check_time
|
63
|
+
@@storage3.update_check_time
|
64
|
+
assert_equal @@storages[0].id, @@policy.get_proper_storage_for_copy(5).id, 'first storages up'
|
65
|
+
assert_nil @@policy.get_proper_storage_for_copy(20), 'first storage full'
|
66
|
+
@@storages[1].update_check_time
|
67
|
+
assert_equal @@storages[1].id, @@policy.get_proper_storage_for_copy(20).id, 'second storages up'
|
68
|
+
assert_nil @@policy.get_proper_storage_for_copy(1000), 'all storages full'
|
69
|
+
|
70
|
+
@@policy.copy_storages = 'rec3-sda,rec1-sda,rec2-sda'
|
71
|
+
@@policy.save
|
72
|
+
assert_equal 'rec3-sda', @@policy.get_proper_storage_for_copy(1).name, 'first storage in copy_storages'
|
73
|
+
assert_equal 'rec2-sda', @@policy.get_proper_storage_for_copy(1, 2).name, 'storage by copy_id'
|
74
|
+
@@policy.copy_storages = 'rec1-sda,rec3-sda'
|
75
|
+
@@policy.save
|
76
|
+
assert_equal 'rec3-sda', @@policy.get_proper_storage_for_copy(1, 2).name, 'storage by copy_id'
|
77
|
+
@@policy.copy_storages = 'rec2-sda,rec3-sda,rec1-sda'
|
78
|
+
@@policy.save
|
79
|
+
assert_equal 'rec2-sda', @@policy.get_proper_storage_for_copy(1, 4).name, 'storage by copy_id'
|
80
|
+
end
|
42
81
|
end
|
data/test/storage_test.rb
CHANGED
@@ -7,7 +7,6 @@ class StorageTest < Test::Unit::TestCase
|
|
7
7
|
|
8
8
|
should "initialize" do
|
9
9
|
assert_raise(RuntimeError) { FC::Storage.new :path => 'test' }
|
10
|
-
assert_raise(RuntimeError) { FC::Storage.new :path => '/test' }
|
11
10
|
assert_raise(RuntimeError) { FC::Storage.new :path => 'test/' }
|
12
11
|
assert_nothing_raised { FC::Storage.new :path => '/test/' }
|
13
12
|
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.0.
|
4
|
+
version: 0.0.9
|
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: 2013-04-
|
12
|
+
date: 2013-04-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rb-readline
|
@@ -186,7 +186,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
186
186
|
version: '0'
|
187
187
|
segments:
|
188
188
|
- 0
|
189
|
-
hash:
|
189
|
+
hash: -919880063
|
190
190
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
191
|
none: false
|
192
192
|
requirements:
|
@@ -195,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
195
|
version: '0'
|
196
196
|
segments:
|
197
197
|
- 0
|
198
|
-
hash:
|
198
|
+
hash: -919880063
|
199
199
|
requirements: []
|
200
200
|
rubyforge_project:
|
201
201
|
rubygems_version: 1.8.24
|