summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Coldrick <adam.coldrick@codethink.co.uk>2015-02-24 08:55:57 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2015-04-20 14:07:40 +0000
commita2c69fb20002f679698c8774f61c7f186f23100d (patch)
treed01e63ec5aecbe7fe98ccae290ca9a2192587c76
parent6821d8234848a7e657434001cc9a904dc670db44 (diff)
downloadmorph-a2c69fb20002f679698c8774f61c7f186f23100d.tar.gz
Create device nodes in staging area
We can't store devices nodes in OSTree, so we can't create them at artifact build time and store them in the chunk artifacts anymore. Instead, we should create them in the staging area when installing an artifact with a source which has a morphology which defines them into the staging area. Change-Id: I423c5e4b8d6595b95894935329c3bf3517cfa475
-rw-r--r--morphlib/builder.py23
-rw-r--r--morphlib/stagingarea.py26
-rw-r--r--morphlib/stagingarea_tests.py25
3 files changed, 39 insertions, 35 deletions
diff --git a/morphlib/builder.py b/morphlib/builder.py
index 524e85a3..735e70aa 100644
--- a/morphlib/builder.py
+++ b/morphlib/builder.py
@@ -246,28 +246,6 @@ class ChunkBuilder(BuilderBase):
'''Build chunk artifacts.'''
- def create_devices(self, destdir): # pragma: no cover
- '''Creates device nodes if the morphology specifies them'''
- morphology = self.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'):
@@ -286,7 +264,6 @@ class ChunkBuilder(BuilderBase):
try:
self.get_sources(builddir)
self.run_commands(builddir, destdir, temppath, stdout)
- self.create_devices(destdir)
os.rename(temppath, logpath)
except BaseException as e:
diff --git a/morphlib/stagingarea.py b/morphlib/stagingarea.py
index ae11dea7..28b22031 100644
--- a/morphlib/stagingarea.py
+++ b/morphlib/stagingarea.py
@@ -154,7 +154,31 @@ class StagingArea(object):
raise IOError('Cannot extract %s into staging-area. Unsupported'
' type.' % srcpath)
- def install_artifact(self, handle):
+ def create_devices(self, morphology): # pragma: no cover
+ '''Creates device nodes if the morphology specifies them'''
+ 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(self.dirname, './' + 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']))
+ parent = os.path.dirname(destfile)
+ if not os.path.exists(parent):
+ os.makedirs(parent)
+ if not os.path.exists(destfile):
+ logging.debug("Creating device node %s" % destfile)
+ os.mknod(destfile, mode,
+ os.makedev(dev['major'], dev['minor']))
+ os.chown(destfile, dev['uid'], dev['gid'])
+
+ def install_artifact(self, artifact, artifact_checkout):
'''Install a build artifact into the staging area.
We access the artifact via an open file handle. For now, we assume
diff --git a/morphlib/stagingarea_tests.py b/morphlib/stagingarea_tests.py
index 4b772e1e..ffdf5eaa 100644
--- a/morphlib/stagingarea_tests.py
+++ b/morphlib/stagingarea_tests.py
@@ -30,6 +30,7 @@ class FakeBuildEnvironment(object):
}
self.extra_path = ['/extra-path']
+
class FakeSource(object):
def __init__(self):
@@ -39,6 +40,12 @@ class FakeSource(object):
self.name = 'le-name'
+class FakeArtifact(object):
+
+ def __init__(self):
+ self.source = FakeSource()
+
+
class FakeApplication(object):
def __init__(self, cachedir, tempdir):
@@ -83,12 +90,8 @@ class StagingAreaTests(unittest.TestCase):
os.mkdir(chunkdir)
with open(os.path.join(chunkdir, 'file.txt'), 'w'):
pass
- chunk_tar = os.path.join(self.tempdir, 'chunk.tar')
- tf = tarfile.TarFile(name=chunk_tar, mode='w')
- tf.add(chunkdir, arcname='.')
- tf.close()
- return chunk_tar
+ return chunkdir
def list_tree(self, root):
files = []
@@ -137,15 +140,15 @@ class StagingAreaTests(unittest.TestCase):
self.assertEqual(self.sa.relative(filename), '/foobar')
def test_installs_artifact(self):
- chunk_tar = self.create_chunk()
- with open(chunk_tar, 'rb') as f:
- self.sa.install_artifact(f)
+ artifact = FakeArtifact()
+ chunkdir = self.create_chunk()
+ self.sa.install_artifact(artifact, chunkdir)
self.assertEqual(self.list_tree(self.staging), ['/', '/file.txt'])
def test_removes_everything(self):
- chunk_tar = self.create_chunk()
- with open(chunk_tar, 'rb') as f:
- self.sa.install_artifact(f)
+ artifact = FakeArtifact()
+ chunkdir = self.create_chunk()
+ self.sa.install_artifact(artifact, chunkdir)
self.sa.remove()
self.assertFalse(os.path.exists(self.staging))