312
def _install_file(klass, path, root):
313
'''Install given file into a chroot, preserving the path.
315
Do nothing if the target file already exists.'''
317
destpath = root + os.path.abspath(path)
318
if os.path.exists(destpath):
320
destdir = os.path.dirname(destpath)
321
if not os.path.isdir(destdir):
323
shutil.copy(path, destdir)
326
def _install_exe(klass, exepath, root):
327
'''Install an executable and all linked shlibs into a chroot.'''
329
klass._install_file(exepath, root)
330
ldd = subprocess.Popen(['ldd', exepath], stdout=subprocess.PIPE)
331
out = ldd.communicate()[0]
332
assert ldd.returncode == 0
333
for m in re.finditer(' => (/[^ ]+)', out):
334
klass._install_file(m.group(1), root)
335
for m in re.finditer('^\s*(/[^ ]+)', out, re.M):
336
klass._install_file(m.group(1), root)
338
def test_shell_ops(self):
339
'''Test various shell operations in the chroot.'''
341
d = tempfile.mkdtemp()
342
ldir = os.path.join(d, 'lib')
344
assert subprocess.call('cp -a /lib/*.so ' + ldir, shell=True) == 0
346
for cmd in ('bash', 'echo', 'cat', 'cp', 'ln', 'ls', 'rm',
347
'mkdir', 'rmdir', 'chmod', 'chown'):
348
self._install_exe('/bin/' + cmd, d)
349
self._install_exe('/usr/bin/stat', d)
353
self.assertEqual(c.run_capture(['echo', 'hello']),
355
self.assertEqual(c.run_capture(['cat'], 'hello'),
357
self.assertEqual(c.run_capture(['/bin/bash'], 'type echo'),
358
('echo is a shell builtin\n', '', 0))
359
self.assertEqual(c.run_capture(['/bin/bash'], 'set -e; false'),
363
(out, err, result) = c.run_capture(['ls'])
364
self.assertEqual(err, '')
365
self.assertEqual(result, 0)
366
files = out.splitlines()
367
self.assert_('bin' in files)
368
self.assert_('lib' in files)
370
# complex shell commands: relative symlinks and paths
371
self.assertEqual(c.run_capture(['bash'], '''set -e
374
echo world > test/file
378
stat -c '%f %s %n' test/file
379
stat -c '%f %n' test/link
380
stat -L -c '%f %s %n' test/link
383
stat -c '%f %s %n' test/file
388
echo world > test/file
391
'''), ('world\nworld\n81a4 6 test/file\na1ff test/link\n81a4 6 test/link\n8180 6 test/file\n', '', 0))
393
# complex shell commands: relative symlink to executable
394
self.assertEqual(c.run_capture(['bash'], '''set -e
397
stat -c '%f %n' bin/eco
398
stat -L -c '%f %n' bin/eco
401
'''), ('a1ff bin/eco\n81ed bin/eco\nhello', '', 0))
403
# complex shell commands: absolute symlinks and paths
404
self.assertEqual(c.run_capture(['bash'], '''set -e
406
echo world > /test/file
407
ln -s /test/file /test/link
410
stat -c '%f %s %n' /test/file
411
stat -c '%f %n' /test/link
412
stat -L -c '%f %s %n' /test/link
415
stat -c '%f %s %n' /test/file
420
echo world > /test/file
423
'''), ('world\nworld\n81a4 6 /test/file\na1ff /test/link\n81a4 6 /test/link\n8180 6 /test/file\n', '', 0))
425
# complex shell commands: absolute symlink to executable
426
self.assertEqual(c.run_capture(['bash'], '''set -e
427
ln -s /bin/echo /bin/eco
430
'''), ('hello', '', 0))
432
# complex shell commands: cp/cat/rm of relative paths
433
self.assertEqual(c.run_capture(['bash'], '''set -e
436
echo "/bin/bash" > etc/shells
437
cp etc/shells etc/shells.tmp
442
'''), ('/bin/bash\n', '', 0))
444
# complex shell commands: cp/cat/rm of absolute paths
445
self.assertEqual(c.run_capture(['bash'], '''set -e
447
echo "/bin/bash" > /etc/shells
448
cp /etc/shells /etc/shells.tmp
453
'''), ('/bin/bash\n', '', 0))