summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmorph119
-rw-r--r--tests.as-root/hello-chunk.tar.gzbin12596 -> 0 bytes
-rw-r--r--tests.as-root/hello-stratum.morph10
-rwxr-xr-xtests.as-root/make-patch.script113
-rw-r--r--tests.as-root/make-patch.stderr0
-rw-r--r--tests.as-root/make-patch.stdout4
-rwxr-xr-xtests.as-root/morph29
7 files changed, 144 insertions, 131 deletions
diff --git a/morph b/morph
index 00653b8f..24c9af3e 100755
--- a/morph
+++ b/morph
@@ -507,57 +507,84 @@ class Morph(cliapp.Application):
tempdir.remove()
def cmd_make_patch(self, args):
- assert os.path.exists(self.settings['cachedir'])
+ '''Create a Trebuchet patch between two system images.'''
- tempdir = morphlib.tempdir.Tempdir(self.settings['tempdir'])
- morph_loader = MorphologyLoader(self.settings)
- src_manager = morphlib.sourcemanager.SourceManager(self, update=False)
- factory = morphlib.builder.Factory(tempdir)
- factory.create_staging()
- builder = morphlib.builder.Builder(tempdir, self, morph_loader,
- src_manager, factory)
- #cachedir = morphlib.cachedir.CacheDir(self.settings['cachedir'])
- ex = morphlib.execute.Execute('.', self.msg)
-
- outpath = args[0]
- args = args[1:]
- trip_iter = self._itertriplets(args)
- paths = {}
- for name in ('source', 'target'):
- repo, ref, filename = trip_iter.next()
- treeish = src_manager.get_treeish(repo, ref)
- morph = morph_loader.load(treeish, filename)
- blob = morphlib.blobs.Blob.create_blob(morph)
- blob_builder = builder.create_blob_builder(blob)
- paths[name] = blob_builder.filename(morph.name)
+ logging.debug('cmd_make_patch starting')
+
+ if len(args) != 7:
+ raise cliapp.AppException('make-patch requires arguments: '
+ 'name of output file plus two triplest')
+ output = args[0]
+ repo_name1, ref1, filename1 = args[1:4]
+ repo_name2, ref2, filename2 = args[4:7]
+
+ self.settings.require('cachedir')
+ cachedir = self.settings['cachedir']
+ build_env = morphlib.buildenvironment.BuildEnvironment(self.settings)
+ ckc = morphlib.cachekeycomputer.CacheKeyComputer(build_env)
+ lac = morphlib.localartifactcache.LocalArtifactCache(cachedir)
+ lrc = morphlib.localrepocache.LocalRepoCache(
+ os.path.join(cachedir, 'gits'),
+ self.settings['git-base-url'],
+ bundle_base_url=self.settings['bundle-server'])
+ rrc = None
+
+ def the_one(source, repo_name, ref, filename):
+ return (source.repo_name == repo_name and
+ source.original_ref == ref and
+ source.filename == filename)
+
+ def get_artifact(repo_name, ref, filename):
+ srcpool = self._create_source_pool(lrc, rrc,
+ (repo_name, ref, filename))
+ ar = morphlib.artifactresolver.ArtifactResolver()
+ artifacts = ar.resolve_artifacts(srcpool)
+ for artifact in artifacts:
+ artifact.cache_key = ckc.compute_key(artifact)
+ if the_one(artifact.source, repo_name, ref, filename):
+ return artifact
+
+ artifact1 = get_artifact(repo_name1, ref1, filename1)
+ artifact2 = get_artifact(repo_name2, ref2, filename2)
+
+ image_path_1 = lac.get(artifact1).name
+ image_path_2 = lac.get(artifact2).name
+
+ def setup(path):
+ part = morphlib.fsutils.setup_device_mapping(ex, path)
+ mount_point = tempfile.mkdtemp()
+ morphlib.fsutils.mount(ex, part, mount_point)
+ return mount_point
+
+ def cleanup(path, mount_point):
+ try:
+ morphlib.fsutils.unmount(ex, mount_point)
+ except:
+ pass
+ try:
+ morphlib.fsutils.undo_device_mapping(ex, path)
+ except:
+ pass
+ try:
+ os.rmdir(mount_point)
+ except:
+ pass
+
+ ex = morphlib.execute.Execute('.', logging.debug)
try:
- for name in paths.iterkeys():
- # mount the system images
- part = morphlib.fsutils.setup_device_mapping(ex, paths[name])
- mount_point = tempdir.join('mnt_' + name)
- morphlib.fsutils.mount(ex, part, mount_point)
-
- # make a diff
- ex.runv(['tbdiff-create', outpath,
- os.path.join(tempdir.join('mnt_source'), 'factory'),
- os.path.join(tempdir.join('mnt_target'), 'factory')])
- except Exception:
+ mount_point_1 = setup(image_path_1)
+ mount_point_2 = setup(image_path_2)
+
+ ex.runv(['tbdiff-create', output,
+ os.path.join(mount_point_1, 'factory'),
+ os.path.join(mount_point_2, 'factory')])
+ except BaseException:
raise
finally:
- # cleanup
- for name in paths.iterkeys():
- mount_point = tempdir.join('mnt_' + name)
- try:
- morphlib.fsutils.unmount(ex, mount_point)
- except:
- pass
- try:
- morphlib.fsutils.undo_device_mapping(ex, paths[name])
- except:
- pass
- factory.remove_staging()
-
+ cleanup(image_path_1, mount_point_1)
+ cleanup(image_path_2, mount_point_2)
+
def cmd_init(self, args):
'''Initialize a mine.'''
diff --git a/tests.as-root/hello-chunk.tar.gz b/tests.as-root/hello-chunk.tar.gz
deleted file mode 100644
index 91e27347..00000000
--- a/tests.as-root/hello-chunk.tar.gz
+++ /dev/null
Binary files differ
diff --git a/tests.as-root/hello-stratum.morph b/tests.as-root/hello-stratum.morph
deleted file mode 100644
index 11ac4e1c..00000000
--- a/tests.as-root/hello-stratum.morph
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "hello",
- "kind": "stratum",
- "sources": {
- "hello": {
- "repo": "hello",
- "ref": "master"
- }
- }
-}
diff --git a/tests.as-root/make-patch.script b/tests.as-root/make-patch.script
index f6793aae..2ffb58cf 100755
--- a/tests.as-root/make-patch.script
+++ b/tests.as-root/make-patch.script
@@ -19,13 +19,11 @@
set -eu
-( # make the dummy stratum contain a chunk for a fake kernel
- mkdir -p "$DATADIR/dummykernel"
- cd "$DATADIR/dummykernel"
- git init --quiet
- cat <<EOF >dummykernel.morph
+# Make a dummy kernel chunk.
+mkdir "$DATADIR/kernel-repo"
+cat <<EOF > "$DATADIR/kernel-repo/linux.morph"
{
- "name": "dummykernel",
+ "name": "linux",
"kind": "chunk",
"install-commands": [
"mkdir -p \"\$DESTDIR/boot\"",
@@ -35,52 +33,75 @@ set -eu
]
}
EOF
-
-
- git add .
- git commit --quiet -m "Make dummy boot files"
+"$SRCDIR/scripts/run-git-in" "$DATADIR/kernel-repo" init --quiet
+"$SRCDIR/scripts/run-git-in" "$DATADIR/kernel-repo" add .
+"$SRCDIR/scripts/run-git-in" "$DATADIR/kernel-repo" commit --quiet -m foo \
+ > /dev/null
- cd "$DATADIR/morphs-repo"
- git checkout --quiet master
- sed -i -e 's/^.*sources.*$/&\
- {\
- "name": "dummykernel",\
- "ref": "master"\
- },\
-/' hello-stratum.morph
+# Make a stratum that include hello and kernel chunks.
+cat <<EOF > "$DATADIR/morphs-repo/hello-stratum.morph"
+{
+ "name": "hello-stratum",
+ "kind": "stratum",
+ "sources": [
+ {
+ "name": "hello",
+ "repo": "chunk-repo",
+ "ref": "farrokh"
+ },
+ {
+ "name": "linux",
+ "repo": "kernel-repo",
+ "ref": "master"
+ }
+ ]
+}
+EOF
+"$SRCDIR/scripts/run-git-in" "$DATADIR/morphs-repo" commit --quiet -am foo \
+ > /dev/null
- git commit --quiet -m "add dummy kernel" hello-stratum.morph
-)
+# Build first image. Remember the stratum.
+"$SRCDIR/scripts/test-morph" build morphs-repo master hello-system.morph
+img1=$(find "$DATADIR/cache" -maxdepth 1 -name '*.system.*')
+stratum1=$(find "$DATADIR/cache" -maxdepth 1 -name '*.stratum.*')
-tests.as-root/morph build morphs-repo master hello-system.morph
+# Modify the chunk, in a new branch.
+"$SRCDIR/scripts/run-git-in" "$DATADIR/chunk-repo" checkout --quiet farrokh
+"$SRCDIR/scripts/run-git-in" "$DATADIR/chunk-repo" checkout --quiet -b alfred
+sed -i s/hello/goodbye/ "$DATADIR/chunk-repo/hello.c"
+"$SRCDIR/scripts/run-git-in" "$DATADIR/chunk-repo" commit -am goodbye \
+ > /dev/null
+
+# Modify the morphs repo to use the new chunk branch, creating a new
+# branch for the morphs repo.
+"$SRCDIR/scripts/run-git-in" "$DATADIR/morphs-repo" checkout --quiet -b alfred
+sed -i 's/farrokh/alfred/' "$DATADIR/morphs-repo/hello-stratum.morph"
+"$SRCDIR/scripts/run-git-in" "$DATADIR/morphs-repo" commit -am goodbye \
+ > /dev/null
-# save the stratum as we will apply the patch on top of this later
-cp "$DATADIR/cache/"*stratum* "$DATADIR"/farrokh-stratum
+# Build second image.
+"$SRCDIR/scripts/test-morph" build morphs-repo alfred hello-system.morph
+img2=$(find "$DATADIR/cache" -maxdepth 1 -name '*.system.*' \
+ ! -name $(basename "$img1"))
-
-( # make an evil stratum
- cd "$DATADIR/chunk-repo"
- git checkout --quiet -b evil farrokh
- sed -i -e 's/hello/goodbye/g' hello.c
- git add hello.c
- git commit --quiet -m "Make the program evil"
+# Make the patch.
+patch="$DATADIR/patch"
+"$SRCDIR/scripts/test-morph" make-patch "$patch" \
+ morphs-repo master hello-system.morph \
+ morphs-repo alfred hello-system.morph --log=/home/liw/foo.log
- cd "$DATADIR/morphs-repo"
- git checkout --quiet -b evil master
- sed -i -e 's/farrokh/evil/g' hello-stratum.morph
- git add hello-stratum.morph
- git commit --quiet -m "Build evil systems"
-)
+# Unpack the original stratum and run the program.
+mkdir "$DATADIR/unpacked"
+cd "$DATADIR/unpacked"
+tar -xf "$stratum1"
+echo "old version:"
+./bin/hello
-tests.as-root/morph build morphs-repo evil hello-system.morph
+# Apply patch, run program again. We should get updated output.
+tbdiff-deploy "$patch" 2>/dev/null
+echo "new version:"
+./bin/hello
-# make a patch to make the system evil
-PATCH="$DATADIR"/patchfile
-tests.as-root/morph make-patch "$PATCH" morphs-repo master hello-system.morph \
- morphs-repo evil hello-system.morph
+# Done.
+echo "Done."
-UNPACKED="$DATADIR"/unpacked
-mkdir -p "$UNPACKED"
-tar -C "$UNPACKED" -xf "$DATADIR"/farrokh-stratum
-(cd "$UNPACKED" && tbdiff-deploy "$PATCH") 2>/dev/null
-"$UNPACKED"/bin/hello
diff --git a/tests.as-root/make-patch.stderr b/tests.as-root/make-patch.stderr
deleted file mode 100644
index e69de29b..00000000
--- a/tests.as-root/make-patch.stderr
+++ /dev/null
diff --git a/tests.as-root/make-patch.stdout b/tests.as-root/make-patch.stdout
index 8b9743b2..b52a681e 100644
--- a/tests.as-root/make-patch.stdout
+++ b/tests.as-root/make-patch.stdout
@@ -1 +1,5 @@
+old version:
+hello, world
+new version:
goodbye, world
+Done.
diff --git a/tests.as-root/morph b/tests.as-root/morph
deleted file mode 100755
index 8ba3ae78..00000000
--- a/tests.as-root/morph
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-#
-# Run morph in a way suitable for tests.
-#
-# Copyright (C) 2012 Codethink Limited
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-set -eu
-
-fatalcat(){
- cat "$1" 1>&2
- return 1
-}
-
-PATH="$(pwd):$PATH"
-./morph --no-default-config --config="$DATADIR/morph.conf" "$@" || \
- fatalcat "$DATADIR/morph.log"