Revision 8797df43

b/lib/utils.py
112 112
  output = property(_GetOutput, None, None, "Return full output")
113 113

  
114 114

  
115
def RunCmd(cmd, env=None, output=None):
115
def RunCmd(cmd, env=None, output=None, cwd='/'):
116 116
  """Execute a (shell) command.
117 117

  
118 118
  The command should not read from its standard input, as it will be
......
126 126
  @param output: if desired, the output of the command can be
127 127
      saved in a file instead of the RunResult instance; this
128 128
      parameter denotes the file name (if not None)
129
  @type cwd: string
130
  @param cwd: if specified, will be used as the working
131
      directory for the command; the default will be /
129 132
  @rtype: L{RunResult}
130 133
  @return: RunResult instance
131 134
  @raise erors.ProgrammerError: if we call this when forks are disabled
......
149 152
    cmd_env.update(env)
150 153

  
151 154
  if output is None:
152
    out, err, status = _RunCmdPipe(cmd, cmd_env, shell)
155
    out, err, status = _RunCmdPipe(cmd, cmd_env, shell, cwd)
153 156
  else:
154
    status = _RunCmdFile(cmd, cmd_env, shell, output)
157
    status = _RunCmdFile(cmd, cmd_env, shell, output, cwd)
155 158
    out = err = ""
156 159

  
157 160
  if status >= 0:
......
163 166

  
164 167
  return RunResult(exitcode, signal_, out, err, strcmd)
165 168

  
166
def _RunCmdPipe(cmd, env, via_shell):
169
def _RunCmdPipe(cmd, env, via_shell, cwd):
167 170
  """Run a command and return its output.
168 171

  
169 172
  @type  cmd: string or list
......
172 175
  @param env: The environment to use
173 176
  @type via_shell: bool
174 177
  @param via_shell: if we should run via the shell
178
  @type cwd: string
179
  @param cwd: the working directory for the program
175 180
  @rtype: tuple
176 181
  @return: (out, err, status)
177 182

  
......
181 186
                           stderr=subprocess.PIPE,
182 187
                           stdout=subprocess.PIPE,
183 188
                           stdin=subprocess.PIPE,
184
                           close_fds=True, env=env)
189
                           close_fds=True, env=env,
190
                           cwd=cwd)
185 191

  
186 192
  child.stdin.close()
187 193
  poller.register(child.stdout, select.POLLIN)
......
218 224
  return out, err, status
219 225

  
220 226

  
221
def _RunCmdFile(cmd, env, via_shell, output):
227
def _RunCmdFile(cmd, env, via_shell, output, cwd):
222 228
  """Run a command and save its output to a file.
223 229

  
224 230
  @type  cmd: string or list
......
229 235
  @param via_shell: if we should run via the shell
230 236
  @type output: str
231 237
  @param output: the filename in which to save the output
238
  @type cwd: string
239
  @param cwd: the working directory for the program
232 240
  @rtype: int
233 241
  @return: the exit status
234 242

  
......
239 247
                             stderr=subprocess.STDOUT,
240 248
                             stdout=fh,
241 249
                             stdin=subprocess.PIPE,
242
                             close_fds=True, env=env)
250
                             close_fds=True, env=env,
251
                             cwd=cwd)
243 252

  
244 253
    child.stdin.close()
245 254
    status = child.wait()
b/test/ganeti.utils_unittest.py
245 245
    finally:
246 246
      os.environ = old_env
247 247

  
248
  def testDefaultCwd(self):
249
    """Test default working directory"""
250
    self.failUnlessEqual(RunCmd(["pwd"]).stdout.strip(), "/")
251

  
252
  def testCwd(self):
253
    """Test default working directory"""
254
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/").stdout.strip(), "/")
255
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/tmp").stdout.strip(), "/tmp")
256
    cwd = os.getcwd()
257
    self.failUnlessEqual(RunCmd(["pwd"], cwd=cwd).stdout.strip(), cwd)
258

  
248 259

  
249 260
class TestRemoveFile(unittest.TestCase):
250 261
  """Test case for the RemoveFile function"""

Also available in: Unified diff