comana 0.0.10 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,223 @@
1
- #! /usr/bin/env ruby
1
+ #s! /usr/bin/env ruby
2
2
  # coding: utf-8
3
+ #
4
+ require "yaml"
5
+
6
+ class Comana::HostInspector
7
+ PING_MIN_INTERVAL = 1
8
+ CACHE_DIR = "#{ENV['HOME']}/var/comana"
9
+
10
+ class NoUpdateFile < Exception; end
11
+
12
+ attr_reader :hostname
13
+
14
+ #
15
+ def initialize(hostname)
16
+ @hostname = hostname
17
+ @cache_dir = "#{CACHE_DIR}/#{@hostname}"
18
+ end
19
+
20
+
21
+ ##ping
22
+ #Try ping three times.
23
+ #Return true if at least one time responds.
24
+ #def ping3
25
+ def update_ping
26
+ result = false
27
+ 3.times do
28
+ command =
29
+ "ping -c 1 -W #{PING_MIN_INTERVAL} #{@hostname} 2> /dev/null 1> /dev/null"
30
+ if system(command)
31
+ result = true
32
+ break
33
+ end
34
+ end
35
+
36
+ write_cache("ping", result)
37
+ end
38
+
39
+ ##cwd
40
+ ##readlink コマンドが使えるかとも思ったが、シムリンク自体の名前が不明瞭になる。
41
+ def update_cwd
42
+ #str = `ssh #{@hostname} 'ls -l /proc/*/cwd'`
43
+ str = ssh_str('ls -l /proc/\*/cwd 2> /dev/null')
44
+ results = {}
45
+ str.split("\n").each do |line|
46
+ #pp line
47
+ items = line.split
48
+ pid = items[8].sub(/^\/proc\//, '').sub(/\/cwd$/, '')
49
+ results[pid] = items[10]
50
+ end
51
+
52
+ write_cache('cwd', results)
53
+ end
54
+
55
+ ##processes
56
+ #%ps auxw
57
+ #USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
58
+ #ippei 28971 0.0 0.0 103684 3764 ? S 15:19 0:00 sshd: ippei@pts/19
59
+ #root 1 0.0 0.0 33876 2280 ? Ss 5月17 0:22 /sbin/init
60
+ #0---------1---------2---------3---------4---------5---------6---------7
61
+ #0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0
62
+ #
63
+ #% ps -o 'user pid %cpu %mem command'
64
+ #USER PID %CPU %MEM COMMAND
65
+ #ippei 19991 0.0 0.2 zsh
66
+ #ippei 23217 0.0 0.0 ps -o user pid %cpu %mem command
67
+ #0---------1---------2---------3---------4---------5---------6---------7
68
+ #0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0-2-4-6-8-0
69
+ #auxw だと、
70
+ #ippei 2948 198 11.8 4495708 3884740 pts/3 Rl Apr01 173494:26 /opt/bin/vasp5212openmpi で桁が崩れることがある。
71
+ def update_ps
72
+ #str = ssh_str('ps -eo "user pid %cpu %mem command"')
73
+ #results = {}
74
+ #lines = str.split("\n")
75
+ #lines.shift # titles of items
76
+ #lines.each do |line|
77
+ # user = line[0..7]
78
+ # pid = line[9..13]
79
+ # cpu = line[15..18]
80
+ # mem = line[20..23]
81
+ # command = line[25..-1]
82
+ # results[pid] = {
83
+ # "user" => user,
84
+ # "cpu" => cpu,
85
+ # "mem" => mem,
86
+ # "command" => command
87
+ # }
88
+ #end
89
+ #write_cache('ps', results)
90
+
91
+ #str = `ssh #{@hostname} 'ps auxw'`
92
+ str = ssh_str('ps auxw')
93
+ results = {}
94
+ lines = str.split("\n")
95
+ lines.shift # titles of items
96
+ lines.each do |line|
97
+ items = line.split
98
+ user = items[0]
99
+ pid = items[1]
100
+ cpu = items[2]
101
+ mem = items[3]
102
+ command = items[10]
103
+
104
+ results[pid] = {
105
+ "user" => user,
106
+ "cpu" => cpu,
107
+ "mem" => mem,
108
+ "command" => command
109
+ }
110
+ end
111
+ write_cache('ps', results)
112
+
113
+ ##str = `ssh #{@hostname} 'ps auxw'`
114
+ #str = ssh_str('ps auxw')
115
+ #results = {}
116
+ #lines = str.split("\n")
117
+ #lines.shift # titles of items
118
+ #lines.each do |line|
119
+ # user = line[0..7]
120
+ # pid = line[9..13]
121
+ # cpu = line[15..18]
122
+ # mem = line[20..23]
123
+ # #vsz = line[25..30]
124
+ # #rss = line[32..36]
125
+ # #tty = line[38..45]
126
+ # #stat = line[47..50]
127
+ # #start = line[52..56]
128
+ # #time = line[58..63]
129
+ # command = line[65..-1]
130
+ # results[pid] = {
131
+ # "user" => user,
132
+ # "cpu" => cpu,
133
+ # "mem" => mem,
134
+ # "command" => command
135
+ # }
136
+ #end
137
+ #write_cache('ps', results)
138
+ end
139
+
140
+ # dmesg ログ形式でつらい。
141
+ # /proc/cpuinfo コアごとにでるのでパースめんどう。
142
+ # lscpu これだと思ったら、CPU MHz がずれてる。ハードウェアで想定される値ではなく、
143
+ # 実際の速度で書かれるらしい。
144
+ # 負荷の有無で値がかわる。
145
+ def update_cpuinfo
146
+ #str = `ssh #{@hostname} 'cat /proc/cpuinfo'`
147
+ str = ssh_str('cat /proc/cpuinfo')
148
+ results = []
149
+ cur_index = 0
150
+ results[cur_index] = {}
151
+ lines = str.split("\n")
152
+ lines.each do |line|
153
+ if line =~ /^\s*$/
154
+ cur_index += 1
155
+ results[cur_index] = {}
156
+ next
157
+ end
158
+ key, value = line.split(/\s*:\s*/)
159
+ results[cur_index][key] = value
160
+ end
161
+ write_cache('cpuinfo', results)
162
+ end
163
+
164
+ def update_meminfo
165
+ #str = `ssh #{@hostname} 'cat /proc/meminfo'`
166
+ str = ssh_str('cat /proc/meminfo')
167
+ results = {}
168
+ lines = str.split("\n")
169
+ lines.each do |line|
170
+ key, value = line.split(/\s*:\s*/)
171
+ results[key] = value
172
+ end
173
+ write_cache('meminfo', results)
174
+ end
175
+
176
+ ############################################################
177
+ ## common
178
+ #Return from cached ping data.
179
+ def fetch(name)
180
+ load_cache(name)
181
+ end
182
+
183
+ def time_updated(name)
184
+ ping_file = "#{@cache_dir}/#{name}.yaml"
185
+ if File.exist? ping_file
186
+ return File.mtime(ping_file)
187
+ else
188
+ return nil
189
+ end
190
+ end
191
+
192
+ private
193
+
194
+ # 先に ping を打ち、返事がなければ 空文字列 を返す。
195
+ def ssh_str(command)
196
+ #pp command
197
+ update_ping
198
+ if fetch('ping')
199
+ return `ssh #{@hostname} #{command}`
200
+ else
201
+ return ''
202
+ end
203
+ end
204
+
205
+ def write_cache(name, value)
206
+ FileUtils.mkdir_p @cache_dir
207
+ File.open("#{@cache_dir}/#{name}.yaml", "w") do |io|
208
+ YAML.dump(value, io)
209
+ end
210
+ end
211
+
212
+ def load_cache(name)
213
+ #return nil unless File.exist? "#{@cache_dir}/#{name}.yaml"
214
+ cache_file = "#{@cache_dir}/#{name}.yaml"
215
+ unless File.exist? cache_file
216
+ raise NoUpdateFile, "#{cache_file} not found."
217
+ end
218
+
219
+ YAML.load_file("#{@cache_dir}/#{name}.yaml")
220
+ end
221
+
222
+ end
3
223
 
4
- module Comana::HostInspector; end
@@ -0,0 +1,34 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ #
5
+ #
6
+ #
7
+ class Comana::QueueManager
8
+ #
9
+ def initialize()
10
+ end
11
+
12
+ #
13
+ def queues
14
+ `qconf -sql`.split("\n")
15
+ end
16
+
17
+ # return a queue name with less tasks.
18
+ def light_queue
19
+ queues.each do |queue|
20
+ hostlist(queue)
21
+ end
22
+
23
+ end
24
+
25
+ def qhost
26
+
27
+ end
28
+
29
+ private
30
+
31
+
32
+
33
+ end
34
+
@@ -4,6 +4,8 @@
4
4
  require "fileutils"
5
5
  #require "comana/computationmanager.rb"
6
6
  #require "comana/clustersetting.rb"
7
+ #
8
+ #For Torque. This class will be obsoleted.
7
9
 
8
10
  #
9
11
  #
@@ -53,7 +55,7 @@ class Comana::QueueSubmitter < Comana::ComputationManager
53
55
  script_path = "#{@dir}/#{SCRIPT}"
54
56
  File.open(script_path, "w") { |io| dump_script(io) }
55
57
 
56
- # run
58
+ # exec
57
59
  system("cd #{@dir}; qsub -l prologue=#{prologue_path} -l epilogue=#{epilogue_path} #{script_path} > jobid.log")
58
60
  end
59
61
 
data/lib/comana.rb CHANGED
@@ -9,5 +9,5 @@ require "comana/clustersetting.rb"
9
9
  require "comana/hostselector.rb"
10
10
  require "comana/queuesubmitter.rb"
11
11
  require "comana/hostinspector.rb"
12
- require "comana/hostinspector/ping.rb"
13
- require "comana/hostinspector/pbsnodes.rb"
12
+ require "comana/queuemanager.rb"
13
+ require "comana/gridenginescript.rb"
@@ -0,0 +1 @@
1
+ var
@@ -0,0 +1,16 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "pp"
5
+ require "helper"
6
+ #require "test/unit"
7
+ #require "pkg/klass.rb"
8
+
9
+
10
+ class TC_GridEngineScript < Test::Unit::TestCase
11
+ def setup
12
+ @g00 = GridEngineScript.new
13
+ end
14
+
15
+ end
16
+
@@ -0,0 +1,112 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "helper"
5
+ #require "test/unit"
6
+ #require "pkg/klass.rb"
7
+
8
+
9
+ class Comana::HostInspector
10
+ CACHE_DIR = "test/hostinspector/var"
11
+ end
12
+
13
+ class TC_HostInspector < Test::Unit::TestCase
14
+ CACHE_DIR = Comana::HostInspector::CACHE_DIR
15
+
16
+ def setup
17
+ @h00 = Comana::HostInspector.new("localhost")
18
+ @h01 = Comana::HostInspector.new("__not_exist_host__")
19
+ end
20
+
21
+ def test_update_ping
22
+ ping_file = "#{CACHE_DIR}/#{@h00.hostname}/ping.yaml"
23
+ #FileUtils.rm_rf "#{CACHE_DIR}/#{@h00.hostname}"
24
+ FileUtils.rm ping_file if File.exist?(ping_file)
25
+ assert_equal(false, File.exist?(ping_file))
26
+ @h00.update_ping
27
+ assert_equal(true, File.exist?(ping_file))
28
+ assert_equal(true, YAML.load_file(ping_file))
29
+
30
+ ping_file = "#{CACHE_DIR}/#{@h01.hostname}/ping.yaml"
31
+ FileUtils.rm ping_file if File.exist?(ping_file)
32
+ assert_equal(false, File.exist?(ping_file))
33
+ @h01.update_ping
34
+ assert_equal(true, File.exist?(ping_file))
35
+ assert_equal(false, YAML.load_file(ping_file))
36
+ end
37
+
38
+ def test_update_cwd
39
+ cwd_file = "#{CACHE_DIR}/#{@h00.hostname}/cwd.yaml"
40
+ FileUtils.rm cwd_file if File.exist?(cwd_file)
41
+ assert_equal(false, File.exist?(cwd_file))
42
+ @h00.update_cwd
43
+ assert_equal(true, File.exist?(cwd_file))
44
+ assert_equal(Hash, YAML.load_file(cwd_file).class)
45
+
46
+ #cwd_file = "#{CACHE_DIR}/#{@h01.hostname}/cwd.yaml"
47
+ #FileUtils.rm cwd_file if File.exist?(cwd_file)
48
+ #assert_equal(false, File.exist?(cwd_file))
49
+ #@h01.update_cwd
50
+ #assert_equal(true, File.exist?(cwd_file))
51
+ #assert_equal(Hash, YAML.load_file(cwd_file).class)
52
+ end
53
+
54
+ def test_update_ps
55
+ ps_file = "#{CACHE_DIR}/#{@h00.hostname}/ps.yaml"
56
+ FileUtils.rm ps_file if File.exist?(ps_file)
57
+ assert_equal(false, File.exist?(ps_file))
58
+ @h00.update_ps
59
+ assert_equal(true, File.exist?(ps_file))
60
+ assert_equal(Hash, YAML.load_file(ps_file).class)
61
+ end
62
+
63
+ def test_update_cpuinfo
64
+ cpuinfo_file = "#{CACHE_DIR}/#{@h00.hostname}/cpuinfo.yaml"
65
+ FileUtils.rm cpuinfo_file if File.exist?(cpuinfo_file)
66
+ assert_equal(false, File.exist?(cpuinfo_file))
67
+ @h00.update_cpuinfo
68
+ assert_equal(true, File.exist?(cpuinfo_file))
69
+
70
+ results = YAML.load_file(cpuinfo_file)
71
+ assert_equal(Array, results.class)
72
+ assert_equal(Hash, results[0].class)
73
+ end
74
+
75
+ def test_update_meminfo
76
+ meminfo_file = "#{CACHE_DIR}/#{@h00.hostname}/meminfo.yaml"
77
+ FileUtils.rm meminfo_file if File.exist?(meminfo_file)
78
+ assert_equal(false, File.exist?(meminfo_file))
79
+ @h00.update_meminfo
80
+ assert_equal(true, File.exist?(meminfo_file))
81
+
82
+ results = YAML.load_file(meminfo_file)
83
+ assert_equal(Hash, results.class)
84
+ end
85
+
86
+ def test_fetch
87
+ @h00.update_ping
88
+ assert_equal(true, @h00.fetch('ping'))
89
+
90
+ @h01.update_ping
91
+ assert_equal(false, @h01.fetch('ping'))
92
+
93
+ ping_file = "#{CACHE_DIR}/#{@h00.hostname}/ping.yaml"
94
+ FileUtils.rm ping_file if File.exist?(ping_file)
95
+ assert_raise(Comana::HostInspector::NoUpdateFile) do
96
+ @h00.fetch('ping')
97
+ end
98
+ @h00.update_ping
99
+ assert_equal(true, @h00.fetch('ping'))
100
+ end
101
+
102
+ def test_time_ping
103
+ time = Time.local(2015, 5, 29, 22, 00, 17)
104
+ ping_file = "#{CACHE_DIR}/#{@h00.hostname}/ping.yaml"
105
+ #pp File.mtime(ping_file)
106
+ File::utime(time, time, ping_file)
107
+ #pp File.mtime(ping_file)
108
+ assert_equal(time, File.mtime(ping_file))
109
+ end
110
+
111
+ end
112
+
@@ -0,0 +1,19 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "helper"
5
+ #require "test/unit"
6
+ #require "pkg/klass.rb"
7
+
8
+ class TC_QueueManager < Test::Unit::TestCase
9
+ def setup
10
+ @qm00 = Comana::QueueManager.new
11
+ end
12
+
13
+ def test_qhost
14
+ @qm00.qhost
15
+
16
+ end
17
+
18
+ end
19
+
metadata CHANGED
@@ -1,103 +1,109 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comana
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - ippei94da
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-08-28 00:00:00.000000000 Z
11
+ date: 2016-03-04 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: test-unit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: rdoc
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ~>
31
+ - - "~>"
20
32
  - !ruby/object:Gem::Version
21
- version: 4.0.1
33
+ version: '4.2'
22
34
  type: :development
23
35
  prerelease: false
24
36
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
37
  requirements:
27
- - - ~>
38
+ - - "~>"
28
39
  - !ruby/object:Gem::Version
29
- version: 4.0.1
40
+ version: '4.2'
30
41
  - !ruby/object:Gem::Dependency
31
42
  name: bundler
32
43
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
44
  requirements:
35
- - - ~>
45
+ - - "~>"
36
46
  - !ruby/object:Gem::Version
37
- version: 1.7.2
47
+ version: '1.11'
38
48
  type: :development
39
49
  prerelease: false
40
50
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
51
  requirements:
43
- - - ~>
52
+ - - "~>"
44
53
  - !ruby/object:Gem::Version
45
- version: 1.7.2
54
+ version: '1.11'
46
55
  - !ruby/object:Gem::Dependency
47
56
  name: jeweler
48
57
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
58
  requirements:
51
- - - ! '>='
59
+ - - "~>"
52
60
  - !ruby/object:Gem::Version
53
- version: 2.0.1
61
+ version: '2.0'
54
62
  type: :development
55
63
  prerelease: false
56
64
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
65
  requirements:
59
- - - ! '>='
66
+ - - "~>"
60
67
  - !ruby/object:Gem::Version
61
- version: 2.0.1
68
+ version: '2.0'
62
69
  - !ruby/object:Gem::Dependency
63
70
  name: simplecov
64
71
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
72
  requirements:
67
- - - ! '>='
73
+ - - "~>"
68
74
  - !ruby/object:Gem::Version
69
- version: '0'
75
+ version: '0.11'
70
76
  type: :development
71
77
  prerelease: false
72
78
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
79
  requirements:
75
- - - ! '>='
80
+ - - "~>"
76
81
  - !ruby/object:Gem::Version
77
- version: '0'
82
+ version: '0.11'
78
83
  - !ruby/object:Gem::Dependency
79
84
  name: tefil
80
85
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
86
  requirements:
83
- - - ! '>='
87
+ - - ">="
84
88
  - !ruby/object:Gem::Version
85
- version: 0.0.3
89
+ version: '0.1'
86
90
  type: :development
87
91
  prerelease: false
88
92
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
93
  requirements:
91
- - - ! '>='
94
+ - - ">="
92
95
  - !ruby/object:Gem::Version
93
- version: 0.0.3
94
- description: ! "Comana, COmputation MANAger,\n is a software to provide a framework
96
+ version: '0.1'
97
+ description: "Comana, COmputation MANAger,\n is a software to provide a framework
95
98
  of\n managing scientific computing.\n Researchers on computing have to check
96
99
  calculation and\n generate new calculation and execute, repeatedly.\n The
97
100
  abstract class that this gem provide would help the work.\n "
98
101
  email: ippei94da@gmail.com
99
102
  executables:
103
+ - genqsub
104
+ - hostinfo
100
105
  - machinestatus
106
+ - queueinfo
101
107
  - scpall
102
108
  - sshall
103
109
  extensions: []
@@ -105,28 +111,33 @@ extra_rdoc_files:
105
111
  - LICENSE.txt
106
112
  - README.rdoc
107
113
  files:
108
- - .document
109
- - .rspec
114
+ - ".document"
115
+ - ".rspec"
110
116
  - CHANGES
111
117
  - Gemfile
112
118
  - LICENSE.txt
113
119
  - README.rdoc
114
120
  - Rakefile
115
121
  - VERSION
122
+ - bin/genqsub
123
+ - bin/hostinfo
116
124
  - bin/machinestatus
125
+ - bin/queueinfo
117
126
  - bin/scpall
118
127
  - bin/sshall
128
+ - comana.gemspec
119
129
  - example/dot.clustersetting
120
130
  - lib/comana.rb
121
131
  - lib/comana/clustersetting.rb
122
132
  - lib/comana/computationmanager.rb
133
+ - lib/comana/gridenginescript.rb
123
134
  - lib/comana/hostinspector.rb
124
- - lib/comana/hostinspector/pbsnodes.rb
125
- - lib/comana/hostinspector/ping.rb
126
135
  - lib/comana/hostselector.rb
136
+ - lib/comana/queuemanager.rb
127
137
  - lib/comana/queuesubmitter.rb
128
138
  - memo.txt
129
139
  - test/helper.rb
140
+ - test/hostinspector/.gitignore
130
141
  - test/locked/input_a
131
142
  - test/locked/input_b
132
143
  - test/locked/lock_comana/dummy
@@ -149,36 +160,33 @@ files:
149
160
  - test/queuesubmitter/unlocked/dummy
150
161
  - test/test_clustersetting.rb
151
162
  - test/test_computationmanager.rb
152
- - test/test_hostinspector_pbsnodes.rb
153
- - test/test_hostinspector_ping.rb
163
+ - test/test_gridenginescript.rb
164
+ - test/test_hostinspector.rb
154
165
  - test/test_hostselector.rb
166
+ - test/test_queuemanager.rb
155
167
  - test/test_queuesubmitter.rb
156
168
  homepage: http://github.com/ippei94da/comana
157
169
  licenses:
158
170
  - MIT
171
+ metadata: {}
159
172
  post_install_message:
160
173
  rdoc_options: []
161
174
  require_paths:
162
175
  - lib
163
176
  required_ruby_version: !ruby/object:Gem::Requirement
164
- none: false
165
177
  requirements:
166
- - - ! '>='
178
+ - - ">="
167
179
  - !ruby/object:Gem::Version
168
180
  version: '0'
169
- segments:
170
- - 0
171
- hash: -3582063889889649984
172
181
  required_rubygems_version: !ruby/object:Gem::Requirement
173
- none: false
174
182
  requirements:
175
- - - ! '>='
183
+ - - ">="
176
184
  - !ruby/object:Gem::Version
177
185
  version: '0'
178
186
  requirements: []
179
187
  rubyforge_project:
180
- rubygems_version: 1.8.23
188
+ rubygems_version: 2.2.3
181
189
  signing_key:
182
- specification_version: 3
190
+ specification_version: 4
183
191
  summary: Manager for scientific computing
184
192
  test_files: []