openvz 1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ module OpenVZ
2
+ class Inventory < ConfigHash
3
+ def load
4
+ s = Shell.new("/usr/sbin/vzlist -a", :cwd => "/tmp")
5
+ s.runcommand
6
+
7
+ ret_code = s.status
8
+ if ret_code != 0
9
+ raise StandardError, "Execution of shell command failed. Command: #{s.command} RC: #{ret_code} Error: #{s.stderr}\n\n"
10
+ end
11
+
12
+ s.stdout.each { |l|
13
+ # inventarize a container object for each avaiable container.
14
+ if l =~ /^\s+(\d+)\s+(.*)\s+(running|stopped)\s+(.*)\s\s(.*)$/
15
+ self[$1] = Container.new($1)
16
+ end
17
+ }
18
+ end
19
+ end
20
+ end
data/lib/openvz/log.rb ADDED
@@ -0,0 +1,67 @@
1
+ module OpenVZ
2
+ # A simple class that allows logging at various levels.
3
+ class Log
4
+ class << self
5
+ @logger = nil
6
+
7
+ # Obtain the class name of the currently configured logger
8
+ def logger
9
+ @logger.class
10
+ end
11
+
12
+ # Logs at info level
13
+ def info(msg)
14
+ log(:info, msg)
15
+ end
16
+
17
+ # Logs at warn level
18
+ def warn(msg)
19
+ log(:warn, msg)
20
+ end
21
+
22
+ # Logs at debug level
23
+ def debug(msg)
24
+ log(:debug, msg)
25
+ end
26
+
27
+ # Logs at fatal level
28
+ def fatal(msg)
29
+ log(:fatal, msg)
30
+ end
31
+
32
+ # Logs at error level
33
+ def error(msg)
34
+ log(:error, msg)
35
+ end
36
+
37
+ # handle old code that relied on this class being a singleton
38
+ def instance
39
+ self
40
+ end
41
+
42
+ # increments the active log level
43
+ def cycle_level
44
+ @logger.cycle_level if @configured
45
+ end
46
+
47
+ # logs a message at a certain level
48
+ def log(level, msg)
49
+ t = Time.new.strftime("%H:%M:%S")
50
+ STDERR.puts "#{t}: #{level}: #{from}: #{msg}"
51
+ end
52
+
53
+ # sets the logger class to use
54
+ def set_logger(logger)
55
+ @logger = logger
56
+ end
57
+
58
+
59
+ # figures out the filename that called us
60
+ def from
61
+ from = File.basename(caller[2])
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ # vi:tabstop=4:expandtab:ai:filetype=ruby
@@ -0,0 +1,90 @@
1
+ module OpenVZ
2
+ #
3
+ # This code is completely borrowed from marionette-collective.
4
+ #
5
+ # Wrapper around systemu that handles executing of system commands
6
+ # in a way that makes stdout, stderr and status available. Supports
7
+ # timeouts and sets a default sane environment.
8
+ #
9
+ # s = Shell.new("date", opts)
10
+ # s.runcommand
11
+ # puts s.stdout
12
+ # puts s.stderr
13
+ # puts s.status.exitcode
14
+ #
15
+ # Options hash can have:
16
+ #
17
+ # cwd - the working directory the command will be run from
18
+ # stdin - a string that will be sent to stdin of the program
19
+ # stdout - a variable that will receive stdout, must support <<
20
+ # stderr - a variable that will receive stdin, must support <<
21
+ # environment - the shell environment, defaults to include LC_ALL=C
22
+ # set to nil to clear the environment even of LC_ALL
23
+ #
24
+ class Shell
25
+ attr_reader :environment, :command, :status, :stdout, :stderr, :stdin, :cwd
26
+
27
+ def initialize(command, options={})
28
+ @environment = {"LC_ALL" => "C"}
29
+ @command = command
30
+ @status = nil
31
+ @stdout = ""
32
+ @stderr = ""
33
+ @stdin = nil
34
+ @cwd = "/tmp"
35
+
36
+ options.each do |opt, val|
37
+ case opt.to_s
38
+ when "stdout"
39
+ raise "stdout should support <<" unless val.respond_to?("<<")
40
+ @stdout = val
41
+
42
+ when "stderr"
43
+ raise "stderr should support <<" unless val.respond_to?("<<")
44
+ @stderr = val
45
+
46
+ when "stdin"
47
+ raise "stdin should be a String" unless val.is_a?(String)
48
+ @stdin = val
49
+
50
+ when "cwd"
51
+ raise "Directory #{val} does not exist" unless File.directory?(val)
52
+ @cwd = val
53
+
54
+ when "environment"
55
+ if val.nil?
56
+ @environment = {}
57
+ else
58
+ @environment.merge!(val.dup)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ # Actually does the systemu call passing in the correct environment, stdout and stderr
65
+ def runcommand
66
+ opts = {"env" => @environment,
67
+ "stdout" => @stdout,
68
+ "stderr" => @stderr,
69
+ "cwd" => @cwd}
70
+
71
+ opts["stdin"] = @stdin if @stdin
72
+
73
+ # Running waitpid on the cid here will start a thread
74
+ # with the waitpid in it, this way even if the thread
75
+ # that started this process gets killed due to agent
76
+ # timeout or such there will still be a waitpid waiting
77
+ # for the child to exit and not leave zombies.
78
+ @status = systemu(@command, opts) do |cid|
79
+ begin
80
+ sleep 1
81
+ Process::waitpid(cid)
82
+ rescue SystemExit
83
+ rescue Errno::ECHILD
84
+ rescue Exception => e
85
+ Log.info("Unexpected exception received while waiting for child process: #{e.class}: #{e}")
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,39 @@
1
+ module OpenVZ
2
+ class Util
3
+ # Generate a mac address based upon three different variables
4
+ def generate_mac(ctid, vlanid, for_host)
5
+ ctid_str = '%06i' % ctid
6
+ vlanid_str = '%04i' % vlanid
7
+
8
+ bridgemac = [0,0,0,0,0,0]
9
+ bridgemac[1] = ctid_str[0..1]
10
+ bridgemac[2] = ctid_str[2..3]
11
+ bridgemac[3] = ctid_str[4..5]
12
+ bridgemac[4] = vlanid_str[0..1]
13
+ bridgemac[5] = vlanid_str[2..3]
14
+
15
+ if for_host
16
+ bridgemac[0] = '12'
17
+ else
18
+ bridgemac[0] = '02'
19
+ end
20
+
21
+ # assemble macstring
22
+ '%s:%s:%s:%s:%s:%s' % bridgemac[0,6]
23
+ end
24
+
25
+ # Search for a specific pattern and replace it with string
26
+ # in file.
27
+ def searchandreplace(file, pattern, replace)
28
+ if File.writeable?(file)
29
+ File.open(file, 'w') do |f|
30
+ $<.each_line do |line|
31
+ f.puts line.gsub(Regexp.new(pattern), replace)
32
+ end
33
+ end
34
+ else
35
+ raise "File not writeable: #{file}."
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,41 @@
1
+ module OpenVZ
2
+ # Simple module to manage vendored code.
3
+ #
4
+ # To vendor a library simply download its whole git repo or untar
5
+ # into vendor/libraryname and create a load_libraryname.rb file
6
+ # to add its libdir into the $:.
7
+ #
8
+ # Once you have that file, add a require line in vendor/require_vendored.rb
9
+ # which will run after all the load_* files.
10
+ #
11
+ # The intention is to not change vendored libraries and to eventually
12
+ # make adding them in optional so that distros can simply adjust their
13
+ # packaging to exclude this directory and the various load_xxx.rb scripts
14
+ # if they wish to install these gems as native packages.
15
+ class Vendor
16
+ class << self
17
+ def vendor_dir
18
+ File.join([File.dirname(File.expand_path(__FILE__)), "vendor"])
19
+ end
20
+
21
+ def load_entry(entry)
22
+ Log.debug("Loading vendored #{$1}")
23
+ load "#{vendor_dir}/#{entry}"
24
+ end
25
+
26
+ def require_libs
27
+ require 'openvz/vendor/require_vendored'
28
+ end
29
+
30
+ def load_vendored
31
+ Dir.entries(vendor_dir).each do |entry|
32
+ if entry.match(/load_(\w+?)\.rb$/)
33
+ load_entry entry
34
+ end
35
+ end
36
+
37
+ require_libs
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1 @@
1
+ $: << File.join([File.dirname(__FILE__), "systemu/lib"])
@@ -0,0 +1 @@
1
+ require 'systemu'
@@ -0,0 +1,160 @@
1
+ NAME
2
+
3
+ systemu
4
+
5
+ SYNOPSIS
6
+
7
+ univeral capture of stdout and stderr and handling of child process pid for windows, *nix, etc.
8
+
9
+ URIS
10
+
11
+ http://rubyforge.org/projects/codeforpeople/
12
+ http://codeforpeople.com/lib/ruby/
13
+ http://codeforpeople.rubyforge.org/svn/
14
+
15
+ INSTALL
16
+
17
+ gem install systemu
18
+
19
+ HISTORY
20
+
21
+ 1.2.0
22
+
23
+ - fixed handling of background thread management - needed
24
+ Thread.current.abort_on_exception = true
25
+
26
+ - fixed reporting of child pid, it was reported as the parent's pid before
27
+
28
+ SAMPLES
29
+
30
+ <========< samples/a.rb >========>
31
+
32
+ ~ > cat samples/a.rb
33
+
34
+ #
35
+ # systemu can be used on any platform to return status, stdout, and stderr of
36
+ # any command. unlike other methods like open3/popen4 there is zero danger of
37
+ # full pipes or threading issues hanging your process or subprocess.
38
+ #
39
+ require 'systemu'
40
+
41
+ date = %q( ruby -e" t = Time.now; STDOUT.puts t; STDERR.puts t " )
42
+
43
+ status, stdout, stderr = systemu date
44
+ p [ status, stdout, stderr ]
45
+
46
+ ~ > ruby samples/a.rb
47
+
48
+ [#<Process::Status: pid=987,exited(0)>, "Thu Dec 06 16:01:59 -0700 2007\n", "Thu Dec 06 16:01:59 -0700 2007\n"]
49
+
50
+
51
+ <========< samples/b.rb >========>
52
+
53
+ ~ > cat samples/b.rb
54
+
55
+ #
56
+ # quite a few keys can be passed to the command to alter it's behaviour. if
57
+ # either stdout or stderr is supplied those objects should respond_to? '<<'
58
+ # and only status will be returned
59
+ #
60
+ require 'systemu'
61
+
62
+ date = %q( ruby -e" t = Time.now; STDOUT.puts t; STDERR.puts t " )
63
+
64
+ stdout, stderr = '', ''
65
+ status = systemu date, 'stdout' => stdout, 'stderr' => stderr
66
+ p [ status, stdout, stderr ]
67
+
68
+ ~ > ruby samples/b.rb
69
+
70
+ [#<Process::Status: pid=992,exited(0)>, "Thu Dec 06 16:01:59 -0700 2007\n", "Thu Dec 06 16:01:59 -0700 2007\n"]
71
+
72
+
73
+ <========< samples/c.rb >========>
74
+
75
+ ~ > cat samples/c.rb
76
+
77
+ #
78
+ # of course stdin can be supplied too. synonyms for 'stdin' include '0' and
79
+ # 0. the other stdio streams have similar shortcuts
80
+ #
81
+ require 'systemu'
82
+
83
+ cat = %q( ruby -e" ARGF.each{|line| puts line} " )
84
+
85
+ status = systemu cat, 0=>'the stdin for cat', 1=>stdout=''
86
+ puts stdout
87
+
88
+ ~ > ruby samples/c.rb
89
+
90
+ the stdin for cat
91
+
92
+
93
+ <========< samples/d.rb >========>
94
+
95
+ ~ > cat samples/d.rb
96
+
97
+ #
98
+ # the cwd can be supplied
99
+ #
100
+ require 'systemu'
101
+ require 'tmpdir'
102
+
103
+ pwd = %q( ruby -e" STDERR.puts Dir.pwd " )
104
+
105
+ status = systemu pwd, 2=>(stderr=''), :cwd=>Dir.tmpdir
106
+ puts stderr
107
+
108
+
109
+ ~ > ruby samples/d.rb
110
+
111
+ /private/tmp
112
+
113
+
114
+ <========< samples/e.rb >========>
115
+
116
+ ~ > cat samples/e.rb
117
+
118
+ #
119
+ # any environment vars specified are merged into the child's environment
120
+ #
121
+ require 'systemu'
122
+
123
+ env = %q( ruby -r yaml -e" puts ENV[ 'answer' ] " )
124
+
125
+ status = systemu env, 1=>stdout='', 'env'=>{ 'answer' => 0b101010 }
126
+ puts stdout
127
+
128
+ ~ > ruby samples/e.rb
129
+
130
+ 42
131
+
132
+
133
+ <========< samples/f.rb >========>
134
+
135
+ ~ > cat samples/f.rb
136
+
137
+ #
138
+ # if a block is specified then it is passed the child pid and run in a
139
+ # background thread. note that this thread will __not__ be blocked during the
140
+ # execution of the command so it may do useful work such as killing the child
141
+ # if execution time passes a certain threshold
142
+ #
143
+ require 'systemu'
144
+
145
+ looper = %q( ruby -e" loop{ STDERR.puts Time.now.to_i; sleep 1 } " )
146
+
147
+ status, stdout, stderr =
148
+ systemu looper do |cid|
149
+ sleep 3
150
+ Process.kill 9, cid
151
+ end
152
+
153
+ p status
154
+ p stderr
155
+
156
+ ~ > ruby samples/f.rb
157
+
158
+ #<Process::Status: pid=1012,signaled(SIGKILL=9)>
159
+ "1196982119\n1196982120\n1196982121\n"
160
+
@@ -0,0 +1,30 @@
1
+ NAME
2
+
3
+ systemu
4
+
5
+ SYNOPSIS
6
+
7
+ univeral capture of stdout and stderr and handling of child process pid for windows, *nix, etc.
8
+
9
+ URIS
10
+
11
+ http://rubyforge.org/projects/codeforpeople/
12
+ http://codeforpeople.com/lib/ruby/
13
+ http://codeforpeople.rubyforge.org/svn/
14
+
15
+ INSTALL
16
+
17
+ gem install systemu
18
+
19
+ HISTORY
20
+
21
+ 1.2.0
22
+
23
+ - fixed handling of background thread management - needed
24
+ Thread.current.abort_on_exception = true
25
+
26
+ - fixed reporting of child pid, it was reported as the parent's pid before
27
+
28
+ SAMPLES
29
+
30
+ @samples