1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import errno
21 import logging
22 import os
23 import os.path
24 import pwd
25 import select
26 import subprocess
27 import sys
28 import time
29 from exception import VMBuilderException, VMBuilderUserError
30
33 self.file = file
34 self.buf = ''
35
37 if attr == 'closed':
38 return self.file.closed
39 else:
40 raise AttributeError()
41
44
46 (ins, foo, bar) = select.select([self.file], [], [], 1)
47
48 if self.file not in ins:
49 return True
50 return False
51
53 if self.file.closed:
54 raise StopIteration()
55
56 while not self.read_will_block():
57 c = self.file.read(1)
58 if not c:
59 self.file.close()
60 if self.buf:
61 return self.buf
62 else:
63 raise StopIteration
64 else:
65 self.buf += c
66 if self.buf.endswith('\n'):
67 ret = self.buf
68 self.buf = ''
69 return ret
70 raise StopIteration()
71
73 """
74 Runs a command.
75
76 Locale is reset to C to make parsing error messages possible.
77
78 @type stdin: string
79 @param stdin: input to provide to the process on stdin. If None, process'
80 stdin will be attached to /dev/null
81 @type ignore_fail: boolean
82 @param ignore_fail: If True, a non-zero exit code from the command will not
83 cause an exception to be raised.
84 @type env: dict
85 @param env: Dictionary of extra environment variables to set in the new process
86
87 @rtype: string
88 @return: string containing the stdout of the process
89 """
90
91 env = kwargs.get('env', {})
92 stdin = kwargs.get('stdin', None)
93 ignore_fail = kwargs.get('ignore_fail', False)
94 stdout = stderr = ''
95 args = [str(arg) for arg in argv]
96 logging.debug(args.__repr__())
97 if stdin:
98 logging.debug('stdin was set and it was a string: %s' % (stdin,))
99 stdin_arg = subprocess.PIPE
100 else:
101 stdin_arg = file('/dev/null', 'r')
102 proc_env = dict(os.environ)
103 proc_env['LANG'] = 'C'
104 proc_env['LC_ALL'] = 'C'
105 proc_env.update(env)
106
107 try:
108 proc = subprocess.Popen(args, stdin=stdin_arg, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env=proc_env)
109 except OSError, error:
110 if error.errno == errno.ENOENT:
111 raise VMBuilderUserError, "Couldn't find the program '%s' on your system" % (argv[0])
112 else:
113 raise VMBuilderUserError, "Couldn't launch the program '%s': %s" % (argv[0], error)
114
115 if stdin:
116 proc.stdin.write(stdin)
117 proc.stdin.close()
118
119 mystdout = NonBufferedFile(proc.stdout)
120 mystderr = NonBufferedFile(proc.stderr)
121
122 while not (mystdout.closed and mystderr.closed):
123
124 select.select([x.file for x in [mystdout, mystderr] if not x.closed], [], [])
125 for buf in mystderr:
126 stderr += buf
127 (ignore_fail and logging.debug or logging.info)(buf.rstrip())
128
129 for buf in mystdout:
130 logging.debug(buf.rstrip())
131 stdout += buf
132
133 status = proc.wait()
134 if not ignore_fail and status != 0:
135 raise VMBuilderException, "Process (%s) returned %d. stdout: %s, stderr: %s" % (args.__repr__(), status, stdout, stderr)
136 return stdout
137
139 """
140 Change ownership of file to $SUDO_USER.
141
142 @type path: string
143 @param path: file or directory to give to $SUDO_USER
144 """
145
146 if 'SUDO_USER' in os.environ:
147 logging.debug('Changing ownership of %s to %s' % (path, os.environ['SUDO_USER']))
148 (uid, gid) = pwd.getpwnam(os.environ['SUDO_USER'])[2:4]
149 os.chown(path, uid, gid)
150
152 """
153 Check if we're running as root, and bail out if we're not.
154 """
155
156 if os.geteuid() != 0:
157 raise VMBuilderUserError("This script must be run as root (e.g. via sudo)")
158
160 """
161 Goes through files and fixes their ownership of them.
162
163 @type files: list
164 @param files: files whose ownership should be fixed up (currently
165 simply calls L{give_to_caller})
166
167 """
168 for file in files:
169 give_to_caller(file)
170
172
173 from Cheetah.Template import Template
174 searchList = []
175 if context:
176 searchList.append(context)
177 searchList.append(vm)
178
179 tmpldirs = [os.path.expanduser('~/.vmbuilder/%s'),
180 os.path.dirname(__file__) + '/plugins/%s/templates',
181 '/etc/vmbuilder/%s']
182
183 if vm.templates:
184 tmpldirs.insert(0,'%s/%%s' % vm.templates)
185
186 tmpldirs = [dir % plugin for dir in tmpldirs]
187
188 for dir in tmpldirs:
189 tmplfile = '%s/%s.tmpl' % (dir, tmplname)
190 if os.path.exists(tmplfile):
191 t = Template(file=tmplfile, searchList=searchList)
192 output = t.respond()
193 logging.debug('Output from template \'%s\': %s' % (tmplfile, output))
194 return output
195
196 raise VMBuilderException('Template %s.tmpl not found in any of %s' % (tmplname, ', '.join(tmpldirs)))
197