1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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', 'w')
102 proc_env = dict(os.environ)
103 proc_env['LANG'] = 'C'
104 proc_env['LC_ALL'] = 'C'
105 proc_env.update(env)
106 proc = subprocess.Popen(args, stdin=stdin_arg, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env=proc_env)
107
108 if stdin:
109 proc.stdin.write(stdin)
110 proc.stdin.close()
111
112 mystdout = NonBufferedFile(proc.stdout)
113 mystderr = NonBufferedFile(proc.stderr)
114
115 while not (mystdout.closed and mystderr.closed):
116
117 select.select([x.file for x in [mystdout, mystderr] if not x.closed], [], [])
118 for buf in mystderr:
119 stderr += buf
120 (ignore_fail and logging.debug or logging.info)(buf.rstrip())
121
122 for buf in mystdout:
123 logging.debug(buf.rstrip())
124 stdout += buf
125
126 status = proc.wait()
127 if not ignore_fail and status != 0:
128 raise VMBuilderException, "Process (%s) returned %d. stdout: %s, stderr: %s" % (args.__repr__(), status, stdout, stderr)
129 return stdout
130
132 """
133 Change ownership of file to $SUDO_USER.
134
135 @type path: string
136 @param path: file or directory to give to $SUDO_USER
137 """
138
139 if 'SUDO_USER' in os.environ:
140 logging.debug('Changing ownership of %s to %s' % (path, os.environ['SUDO_USER']))
141 (uid, gid) = pwd.getpwnam(os.environ['SUDO_USER'])[2:4]
142 os.chown(path, uid, gid)
143
145 """
146 Check if we're running as root, and bail out if we're not.
147 """
148
149 if os.geteuid() != 0:
150 raise VMBuilderUserError("This script must be run as root (e.g. via sudo)")
151
153 """
154 Goes through files and fixes their ownership of them.
155
156 @type files: list
157 @param files: files whose ownership should be fixed up (currently
158 simply calls L{give_to_caller})
159
160 """
161 for file in files:
162 give_to_caller(file)
163
165
166 from Cheetah.Template import Template
167 searchList = []
168 if context:
169 searchList.append(context)
170 searchList.append(vm)
171
172 tmpldirs = ['VMBuilder/plugins/%s/templates',
173 os.path.expanduser('~/.vmbuilder/%s'),
174 '/etc/vmbuilder/%s']
175
176 if vm.templates:
177 tmpldirs.insert(0,'%s/%%s' % vm.templates)
178
179 tmpldirs = [dir % plugin for dir in tmpldirs]
180
181 for dir in tmpldirs:
182 tmplfile = '%s/%s.tmpl' % (dir, tmplname)
183 if os.path.exists(tmplfile):
184 t = Template(file=tmplfile, searchList=searchList)
185 output = t.respond()
186 logging.debug('Output from template \'%s\': %s' % (tmplfile, output))
187 return output
188
189 raise VMBuilderException('Template %s.tmpl not found in any of %s' % (tmplname, ', '.join(tmpldirs)))
190