diff options
author | Jonathan Maw <jonathan.maw@codethink.co.uk> | 2013-02-26 11:15:42 +0000 |
---|---|---|
committer | Jonathan Maw <jonathan.maw@codethink.co.uk> | 2013-02-28 11:39:54 +0000 |
commit | 4474a163f78c8e1ea6cee9e594b5b8f7679ddb3f (patch) | |
tree | a7de4b0d203c6cdbf93a52870dcde33918f56164 /morphlib/builder2.py | |
parent | 4440e2ec57bc82ab767b2bca55d6d8d4bfaf897f (diff) | |
download | morph-4474a163f78c8e1ea6cee9e594b5b8f7679ddb3f.tar.gz |
Add the ability for chunk morphs to specify devices
Within a linux-user-chroot, we do not want to allow arbitrary code to
create device nodes, but still want it to be possible to create a device
node. This commit creates and handles the 'devices' field in a chunk
morphology, which takes:
* filename. A string, e.g. "/dev/null"
* uid. The ID of the user the file belongs to, e.g. 0 for root.
* gid. The ID of the group the file belongs to, e.g. 0 for root.
* type. A string of either 'c' for a character device or 'b' for a block
device.
* major. The device's major number.
* minor. The device's minor number.
* permissions. A string of the octal number that would be passed to chmod
e.g. '0777'
Diffstat (limited to 'morphlib/builder2.py')
-rw-r--r-- | morphlib/builder2.py | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/morphlib/builder2.py b/morphlib/builder2.py index 14d73630..82a95820 100644 --- a/morphlib/builder2.py +++ b/morphlib/builder2.py @@ -20,6 +20,7 @@ import json import logging import os import shutil +import stat import time from collections import defaultdict import tarfile @@ -265,6 +266,28 @@ class ChunkBuilder(BuilderBase): else: return morphology[which] + def create_devices(self, destdir): # pragma: no cover + '''Creates device nodes if the morphology specifies them''' + morphology = self.artifact.source.morphology + perms_mask = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO + if 'devices' in morphology and morphology['devices'] is not None: + for dev in morphology['devices']: + destfile = os.path.join(destdir, './' + dev['filename']) + mode = int(dev['permissions'], 8) & perms_mask + if dev['type'] == 'c': + mode = mode | stat.S_IFCHR + elif dev['type'] == 'b': + mode = mode | stat.S_IFBLK + else: + raise IOError('Cannot create device node %s,' + 'unrecognized device type "%s"' + % (destfile, dev['type'])) + self.app.status(msg="Creating device node %s" + % destfile) + os.mknod(destfile, mode, + os.makedev(dev['major'], dev['minor'])) + os.chown(destfile, dev['uid'], dev['gid']) + def build_and_cache(self): # pragma: no cover with self.build_watch('overall-build'): @@ -279,6 +302,7 @@ class ChunkBuilder(BuilderBase): 'build-log') as log: log_name = log.real_filename self.run_commands(builddir, destdir, log) + self.create_devices(destdir) except: self.staging_area.chroot_close() if log_name: |