openvz 1.1
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/COPYING +202 -0
- data/lib/openvz.rb +21 -0
- data/lib/openvz/confighash.rb +45 -0
- data/lib/openvz/container.rb +341 -0
- data/lib/openvz/inventory.rb +20 -0
- data/lib/openvz/log.rb +67 -0
- data/lib/openvz/shell.rb +90 -0
- data/lib/openvz/util.rb +39 -0
- data/lib/openvz/vendor.rb +41 -0
- data/lib/openvz/vendor/load_systemu.rb +1 -0
- data/lib/openvz/vendor/require_vendored.rb +1 -0
- data/lib/openvz/vendor/systemu/README +160 -0
- data/lib/openvz/vendor/systemu/README.tmpl +30 -0
- data/lib/openvz/vendor/systemu/a.rb +6 -0
- data/lib/openvz/vendor/systemu/gemspec.rb +23 -0
- data/lib/openvz/vendor/systemu/gen_readme.rb +32 -0
- data/lib/openvz/vendor/systemu/install.rb +206 -0
- data/lib/openvz/vendor/systemu/lib/systemu.rb +299 -0
- data/lib/openvz/vendor/systemu/samples/a.rb +11 -0
- data/lib/openvz/vendor/systemu/samples/b.rb +12 -0
- data/lib/openvz/vendor/systemu/samples/c.rb +10 -0
- data/lib/openvz/vendor/systemu/samples/d.rb +11 -0
- data/lib/openvz/vendor/systemu/samples/e.rb +9 -0
- data/lib/openvz/vendor/systemu/samples/f.rb +18 -0
- data/openvz.gemspec +48 -0
- metadata +90 -0
@@ -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
|
data/lib/openvz/shell.rb
ADDED
@@ -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
|
data/lib/openvz/util.rb
ADDED
@@ -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
|