svengali 0.2.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/LICENSE +20 -0
  2. data/README +0 -0
  3. data/README.rdoc +17 -0
  4. data/Rakefile +47 -0
  5. data/VERSION +1 -0
  6. data/api_document020_en.pdf +0 -0
  7. data/api_document020_ja.pdf +0 -0
  8. data/api_document_en.pptx +0 -0
  9. data/api_document_ja.pptx +0 -0
  10. data/lib/svengali.rb +2 -0
  11. data/lib/svengali/config.rb +78 -0
  12. data/lib/svengali/ext_string.rb +55 -0
  13. data/lib/svengali/ext_string/command.yml +6 -0
  14. data/lib/svengali/ext_string/path.yml +6 -0
  15. data/lib/svengali/file_io.rb +106 -0
  16. data/lib/svengali/machine.rb +123 -0
  17. data/lib/svengali/platforms/debian.rb +5 -0
  18. data/lib/svengali/platforms/default.rb +4 -0
  19. data/lib/svengali/plugins/eucalyptus.rb +339 -0
  20. data/lib/svengali/plugins/machine_config.rb +126 -0
  21. data/lib/svengali/plugins/package.rb +7 -0
  22. data/lib/svengali/ssh.rb +106 -0
  23. data/lib/svengali/svengali.rb +19 -0
  24. data/lib/svengali/util.rb +117 -0
  25. data/rdoc/classes/CLibIPAddr.html +230 -0
  26. data/rdoc/classes/Cloud.html +506 -0
  27. data/rdoc/classes/Config.html +151 -0
  28. data/rdoc/classes/Config/ConfigFile.html +319 -0
  29. data/rdoc/classes/ExtStr.html +209 -0
  30. data/rdoc/classes/ExtStrAccessor.html +183 -0
  31. data/rdoc/classes/FileIO.html +415 -0
  32. data/rdoc/classes/Machine.html +771 -0
  33. data/rdoc/classes/MachineMaster.html +117 -0
  34. data/rdoc/classes/Platform.html +121 -0
  35. data/rdoc/classes/SSH.html +315 -0
  36. data/rdoc/created.rid +1 -0
  37. data/rdoc/files/README.html +101 -0
  38. data/rdoc/files/README_rdoc.html +133 -0
  39. data/rdoc/files/lib/svengali/config_rb.html +114 -0
  40. data/rdoc/files/lib/svengali/ext_string_rb.html +108 -0
  41. data/rdoc/files/lib/svengali/file_io_rb.html +115 -0
  42. data/rdoc/files/lib/svengali/machine_rb.html +108 -0
  43. data/rdoc/files/lib/svengali/platforms/debian_rb.html +107 -0
  44. data/rdoc/files/lib/svengali/platforms/default_rb.html +107 -0
  45. data/rdoc/files/lib/svengali/plugins/eucalyptus_rb.html +389 -0
  46. data/rdoc/files/lib/svengali/plugins/machine_config_rb.html +101 -0
  47. data/rdoc/files/lib/svengali/plugins/package_rb.html +101 -0
  48. data/rdoc/files/lib/svengali/ssh_rb.html +110 -0
  49. data/rdoc/files/lib/svengali/svengali_rb.html +125 -0
  50. data/rdoc/files/lib/svengali/util_rb.html +439 -0
  51. data/rdoc/files/lib/svengali_rb.html +108 -0
  52. data/rdoc/fr_class_index.html +37 -0
  53. data/rdoc/fr_file_index.html +41 -0
  54. data/rdoc/fr_method_index.html +100 -0
  55. data/rdoc/index.html +26 -0
  56. data/rdoc/rdoc-style.css +208 -0
  57. data/spec/spec.opts +1 -0
  58. data/spec/spec_helper.rb +9 -0
  59. data/spec/svengali_spec.rb +7 -0
  60. data/svengali.gemspec +113 -0
  61. data/svengali_sample.rb +43 -0
  62. data/test/scenario.sh +3 -0
  63. metadata +179 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Ryo Kanbayashi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
File without changes
@@ -0,0 +1,17 @@
1
+ = svengali
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Ryo Kanbayashi. See LICENSE for details.
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "svengali"
8
+ gem.summary = "distributed machine operating library of cloud age. please see http://sourceforge.jp/projects/svengali/wiki/FrontPage"
9
+ gem.description = "Svengali offers means to manage and operate distributed machines easier than by other tools like shell script"
10
+ gem.email = "ryo.contact [at] gmail.com"
11
+ gem.homepage = "http://sourceforge.jp/projects/svengali/"
12
+ gem.authors = ["Ryo Kanbayashi"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency "net-ssh", ">= 2.0.17"
15
+ gem.add_dependency "net-sftp", ">= 2.0.4"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "svengali #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.7.2
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,2 @@
1
+ require "svengali/svengali"
2
+
@@ -0,0 +1,78 @@
1
+ #for StringIO
2
+ require "stringio"
3
+
4
+ module Config
5
+
6
+ # if there isn't a file which has specified file name, New file is created.
7
+ def get_config_file(remote_filepath_str)
8
+ # passed @sftp_session is not one of ConfigFile
9
+ return ConfigFile.new(remote_filepath_str,@sftp_session)
10
+ end
11
+
12
+ class ConfigFile
13
+ include FileIO
14
+
15
+ @remote_filepath_str
16
+ @sftp_session
17
+ #Net::SFTP::Request
18
+ @config_file_contents
19
+
20
+ #ssh_session => Net::SFTP::Session
21
+ #ConfigFile class doesn't manage passed sftp_session value
22
+ def initialize(remote_path_str,sftp_session)
23
+ @sftp_session = sftp_session
24
+
25
+ @remote_filepath_str = remote_path_str
26
+ if is_exist(remote_path_str)
27
+ # config_file = @sftp_session.open!(remote_path_str)
28
+ @config_file_contents = get_contents_remote(@remote_filepath_str)
29
+ else
30
+ @config_file_contents = ""
31
+ end
32
+
33
+ end
34
+
35
+ #replace columns which has specified content
36
+ def replace_col(original_col_str,replaced_col_str)
37
+ orig_contents_io = StringIO.new(@config_file_contents)
38
+ replaced_contents_io = StringIO.new()
39
+ orig_contents_io.each_line { |line|
40
+ replaced_contents_io.puts(line.gsub(original_col_str,replaced_col_str))
41
+ }
42
+ orig_contents_io.close()
43
+ replaced_contents_io.close()
44
+
45
+ @config_file_contents = replaced_contents_io.string
46
+ end
47
+
48
+ def append_str(str)
49
+ @config_file_contents += str
50
+ end
51
+
52
+ #remove all columns which contains passed string
53
+ def remove_col_by_str(str)
54
+ orig_contents_io = StringIO.new(@config_file_contents)
55
+ removed_contents_io = StringIO.new()
56
+ orig_contents_io.each_line { |line|
57
+ unless line.index(str)
58
+ removed_contents_io.puts(line)
59
+ end
60
+ }
61
+ orig_contents_io.close()
62
+ removed_contents_io.close()
63
+
64
+ @config_file_contents = removed_contents_io.string
65
+ end
66
+
67
+ #remove columns which matched passed regular expression
68
+ def remove_col_by_regexp(regexp)
69
+ not_inp()
70
+ end
71
+
72
+ #save modified content
73
+ def save
74
+ write_contents_remote(@remote_filepath_str,@config_file_contents)
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,55 @@
1
+ require "yaml"
2
+
3
+ # manages externarized strings on YAML files
4
+ class ExtStr
5
+ @@command_accessor = nil
6
+ @@path_accessor = nil
7
+
8
+ def self.path()
9
+ unless @@command_accessor && @@path_accessor
10
+ self.init()
11
+ end
12
+
13
+ return @@path_accessor
14
+ end
15
+
16
+ def self.cmd()
17
+ unless @@command_accessor && @@path_accessor
18
+ self.init()
19
+ end
20
+
21
+ return @@command_accessor
22
+ end
23
+
24
+ def self.init()
25
+ @@command_accessor = ExtStrAccessor.new(File::dirname(__FILE__) + "/ext_string/command.yml",$platform_name)
26
+ @@path_accessor = ExtStrAccessor.new( File::dirname(__FILE__) + "/ext_string/path.yml",$platform_name)
27
+ end
28
+ # private_class_method :init
29
+
30
+ end
31
+
32
+ class ExtStrAccessor
33
+ @contents_hash
34
+ @first_level
35
+
36
+ def initialize(file_name_str,first_level_name)
37
+ @contents_hash = YAML.load_file( file_name_str )
38
+ @first_level = first_level_name
39
+ end
40
+
41
+ def [](key)
42
+ val = @contents_hash[@first_level][key]
43
+ if val
44
+ return val
45
+ else
46
+ default_val = @contents_hash["default"][val]
47
+ if default_val
48
+ return default_val
49
+ else
50
+ debug_p "key( #{key.to_s} ) is not found on even default hash!"
51
+ end
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,6 @@
1
+ default:
2
+ package_install: yum install -y
3
+ debian:
4
+ package_install: apt-get install
5
+
6
+
@@ -0,0 +1,6 @@
1
+ default:
2
+ sshd_config: /etc/ssh/sshd_config
3
+ network_configs: /etc/sysconfig/network-scripts/
4
+ resolver_config: /etc/sysconfig/network-scripts/ifcfg-eth0
5
+ debian:
6
+ network_configs: /etc/network/
@@ -0,0 +1,106 @@
1
+ #in this file methods for file trasfer is defined
2
+ require 'rubygems'
3
+ gem 'net-sftp'
4
+ require 'net/sftp'
5
+
6
+ module FileIO
7
+ BUFFER_SIZE = 1024
8
+
9
+ def push_a_file(local_path,remote_path)
10
+ debug_p("push_a_file from #{local_path} to #{remote_path}")
11
+ @sftp_session.upload!(local_path,remote_path)
12
+ end
13
+
14
+ def pull_a_file(remote_path,local_path)
15
+ debug_p("pull_a_file from #{remote_path} to #{local_path}")
16
+
17
+ begin
18
+ @sftp_session.download!(remote_path,local_path)
19
+ rescue
20
+ debug_p remote_path + " is not found on remote!!"
21
+ return nil
22
+ end
23
+ end
24
+
25
+ # push files on specified dir. only one level.
26
+ # directories are not copied.
27
+ def push_files(local_path,remote_path)
28
+ debug_p("push_files from #{local_path} to #{remote_path}")
29
+ local_dir = Dir.new(local_path)
30
+ local_dir.each{ |path|
31
+ unless File::ftype(local_path + "/" + path) == "directory"
32
+ @sftp_session.upload!(local_path + "/" + path,remote_path + "/" + path)
33
+ end
34
+ }
35
+ end
36
+
37
+ #pull files on specified dir. only one level.
38
+ def pull_files(remote_path,local_path)
39
+ debug_p("pull_files from #{remote_path} to #{local_path}")
40
+ @sftp_session.dir.foreach(remote_path){ |path|
41
+ #unless path.name == "." || path.name == ".."
42
+ #not directory
43
+ unless /^d/ =~ path.longname
44
+ @sftp_session.download!(remote_path + "/" + path.name,local_path + "/" + path.name)
45
+ end
46
+ #end
47
+ }
48
+ end
49
+
50
+ # Note: if there is a directory which has same name with *local_path*, remote_directory is removed before coping directory
51
+ def push_dir(local_path,remote_path)
52
+ debug_p("push_dir from #{local_path} to #{remote_path}")
53
+ begin
54
+ @sftp_session.upload!(local_path,remote_path)
55
+ rescue
56
+ @ssh.exec!("rm -rf #{remote_path}")
57
+ retry
58
+ end
59
+ end
60
+
61
+ def pull_dir(remote_path,local_path)
62
+ debug_p("pull_dir from #{remote_path} to #{local_path}")
63
+ begin
64
+ @sftp_session.download!(remote_path,local_path,:recursive => true)
65
+ rescue
66
+ debug_p remote_path + " is not found on remote!!"
67
+ return nil
68
+ end
69
+ end
70
+
71
+ # return -> boolean :
72
+ def is_exist(remote_path)
73
+ begin
74
+ @sftp_session.stat!(remote_path) { |response|
75
+ #returns whether exists or not
76
+ next response.ok?
77
+ }
78
+ rescue => e
79
+ return false
80
+ end
81
+ end
82
+
83
+
84
+ def get_contents_remote(remote_filepath_str)
85
+ debug_p("get_contents_remote from #{remote_filepath_str}")
86
+ handle = @sftp_session.open!(remote_filepath_str)
87
+ contents = String.new()
88
+ offset = 0
89
+ while (data = @sftp_session.read!(handle, offset, BUFFER_SIZE)) != nil
90
+ contents += data
91
+ offset += BUFFER_SIZE
92
+ end
93
+ @sftp_session.close!(handle)
94
+
95
+ return contents
96
+ end
97
+
98
+ # over writes contens from the start
99
+ def write_contents_remote(remote_filepath_str,contents_str)
100
+ debug_p("write_contents_remote to #{remote_filepath_str}")
101
+ handle = @sftp_session.open!(remote_filepath_str,"w")
102
+ @sftp_session.write!(handle, 0, contents_str)
103
+ @sftp_session.close!(handle)
104
+ end
105
+
106
+ end
@@ -0,0 +1,123 @@
1
+ require "thread"
2
+ require "#{LIBNAME}/ssh"
3
+ require "#{LIBNAME}/config"
4
+ require "#{LIBNAME}/util"
5
+ require "#{LIBNAME}/ext_string"
6
+
7
+ #module Machine
8
+ class MachineMaster
9
+ @@group = ThreadGroup.new
10
+ end
11
+
12
+ class Machine < MachineMaster
13
+ include Config
14
+ include FileIO
15
+
16
+ #fields
17
+ @user_name
18
+ @host
19
+ @ssh
20
+ @sftp_session
21
+ @password
22
+ @passphrase
23
+ @private_key_path
24
+
25
+ attr_reader :ssh
26
+
27
+ def initialize(host=nil)
28
+ if host == nil #substitute of constructor which has no argument
29
+ else
30
+ @host = host.to_s()
31
+ initialize()
32
+ end
33
+ end
34
+
35
+ def cleanup
36
+ debug_p "start cleanup instance for " + @host
37
+ @sftp_session.close_channel()
38
+ @ssh.close()
39
+ debug_p "finished cleanup instance for " + @host
40
+ # @@group.list.each {|th| th.join }
41
+ end
42
+
43
+ # def set_auth_info(user_name)
44
+ # @user_name = user_name
45
+ # end
46
+
47
+ def set_auth_info(user_name,password = nil)
48
+ @user_name = user_name
49
+ @password = password
50
+ end
51
+
52
+ def set_auth_info_pki(user_name,passphrase,private_key_path)
53
+ @user_name = user_name
54
+ @passphrase = passphrase
55
+ @private_key_path = private_key_path
56
+ end
57
+
58
+ def establish_session()
59
+ debug_p "start establish_session to " + @host
60
+ # Spawn worker threads
61
+
62
+ th = Thread.new do
63
+ debug_p "Initialization of Machine ##{@host} is started."
64
+ if @private_key_path
65
+ if @user_name && @passphrase
66
+ @ssh = SSH.new(@host,@user_name,@passphrase)
67
+ else
68
+ debug_p "please set user name and password when you want to use public key authentication"
69
+ exit()
70
+ end
71
+ elsif @user_name && @password
72
+ @ssh = SSH.new(@host,@user_name,@password)
73
+ elsif @user_name
74
+ @ssh = SSH.new(@userneme)
75
+ else
76
+ debug_p "please set user name at leaset"
77
+ exit()
78
+ end
79
+ debug_p "Initialization of Machine ##{@host} is finished."
80
+
81
+ @sftp_session = @ssh.sftp_session
82
+ @@group.add(th)
83
+ end
84
+
85
+ #wait until finishing initialize of @ssh object
86
+ while @ssh == nil
87
+ sleep(1)
88
+ end
89
+
90
+ debug_p "finished establish_session to " + @host
91
+ end
92
+
93
+ def exec(command_str)
94
+ return @ssh.exec(command_str)
95
+ end
96
+
97
+ def exec!(command_str,timeout = nil)
98
+ return @ssh.exec!(command_str,timeout)
99
+ end
100
+
101
+ # call exec!( command ) on specified path
102
+ # TODO: change function name to exec_on!
103
+ def exec_on!(command_str,current_path_str)
104
+ exec!("cd #{current_path_str};" + command_str)
105
+ end
106
+
107
+ # execute local script on remote
108
+ # current_path_str -> string: if change of directory is not needed, please pass "."
109
+ # use remote /tmp directory to store script file
110
+ # TODO: change function name to exec_script_on!
111
+ def exec_script_on(script_path_str,arguments_str,current_path_str)
112
+ fname_str = File.basename(script_path_str)
113
+ rempte_path_str = "/tmp/" + fname_str
114
+ push_a_file(script_path_str,rempte_path_str)
115
+ exec_on!("sh #{rempte_path_str} " + arguments_str,current_path_str)
116
+ end
117
+
118
+ def sftp()
119
+ return @ssh.sftp_session
120
+ end
121
+
122
+ end
123
+ #end