summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2014-03-14 11:33:48 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2014-03-14 11:33:48 +0000
commit992ba526e7fd39920b4ede8867bbb8535bfdbb5e (patch)
tree592626681db8abd3f22942b78c8cc515809bf070
parenta0fefde8c4900269bb227f1986324b77a7511664 (diff)
parent95df3b251b455843683b6e24aa4c76ed80beb724 (diff)
downloadmorph-992ba526e7fd39920b4ede8867bbb8535bfdbb5e.tar.gz
Merge branch 'baserock/richardmaw/S10630-multi-deploy-v2'
Reviewed-by: Richard Ipsum and Lars Wirzenius
-rwxr-xr-xmorphlib/exts/sysroot.write29
-rw-r--r--morphlib/plugins/deploy_plugin.py181
-rw-r--r--morphlib/stagingarea_tests.py2
-rwxr-xr-xscripts/edit-morph108
-rwxr-xr-xtests.as-root/rootfs-tarball-builds-rootfs-and-kernel.script2
-rwxr-xr-xtests.merging/setup2
-rw-r--r--yarns/deployment.yarn71
-rw-r--r--yarns/implementations.yarn75
-rw-r--r--yarns/regression.yarn7
-rw-r--r--yarns/splitting.yarn7
10 files changed, 368 insertions, 116 deletions
diff --git a/morphlib/exts/sysroot.write b/morphlib/exts/sysroot.write
new file mode 100755
index 00000000..1ae4864f
--- /dev/null
+++ b/morphlib/exts/sysroot.write
@@ -0,0 +1,29 @@
+#!/bin/sh
+# Copyright (C) 2014 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.
+
+# A Morph write extension to deploy to another directory
+
+set -eu
+
+# Ensure the target is an empty directory
+mkdir -p "$2"
+find "$2" -mindepth 1 -delete
+
+# Move the contents of our source directory to our target
+# Previously we would (cd "$1" && find -print0 | cpio -0pumd "$absolute_path")
+# to do this, but the source directory is disposable anyway, so we can move
+# its contents to save time
+find "$1" -maxdepth 1 -mindepth 1 -exec mv {} "$2/." +
diff --git a/morphlib/plugins/deploy_plugin.py b/morphlib/plugins/deploy_plugin.py
index 61e1b5a4..cc2076cd 100644
--- a/morphlib/plugins/deploy_plugin.py
+++ b/morphlib/plugins/deploy_plugin.py
@@ -26,13 +26,6 @@ import uuid
import morphlib
-# UGLY HACK: We need to re-use some code from the branch and merge
-# plugin, so we import and instantiate that plugin. This needs to
-# be fixed by refactoring the codebase so the shared code is in
-# morphlib, not in a plugin. However, this hack lets us re-use
-# code without copying it.
-import morphlib.plugins.branch_and_merge_plugin
-
class ExtensionNotFoundError(morphlib.Error):
pass
@@ -51,9 +44,6 @@ class DeployPlugin(cliapp.Plugin):
self.app.add_subcommand(
'deploy', self.deploy,
arg_synopsis='CLUSTER [SYSTEM.KEY=VALUE]')
- self.other = \
- morphlib.plugins.branch_and_merge_plugin.BranchAndMergePlugin()
- self.other.app = self.app
def disable(self):
pass
@@ -271,6 +261,11 @@ class DeployPlugin(cliapp.Plugin):
'''
+ # Nasty hack to allow deploying things of a different architecture
+ def validate(self, root_artifact):
+ pass
+ morphlib.buildcommand.BuildCommand._validate_architecture = validate
+
if not args:
raise cliapp.AppException(
'Too few arguments to deploy command (see help)')
@@ -337,55 +332,94 @@ class DeployPlugin(cliapp.Plugin):
ref=build_ref, dirname=gd.dirname,
remote=remote.get_push_url(), chatty=True)
- for system in cluster_morphology['systems']:
- self.deploy_system(build_command, root_repo_dir,
- bb.root_repo_url, bb.root_ref,
- system, env_vars)
-
- def deploy_system(self, build_command, root_repo_dir, build_repo, ref,
- system, env_vars):
- # Find the artifact to build
- morph = system['morph']
- srcpool = build_command.create_source_pool(build_repo, ref,
- morph + '.morph')
- def validate(self, root_artifact):
- pass
- morphlib.buildcommand.BuildCommand._validate_architecture = validate
-
- artifact = build_command.resolve_artifacts(srcpool)
-
- deploy_defaults = system['deploy-defaults']
- deployments = system['deploy']
- for system_id, deploy_params in deployments.iteritems():
- user_env = morphlib.util.parse_environment_pairs(
- os.environ,
- [pair[len(system_id)+1:]
- for pair in env_vars
- if pair.startswith(system_id)])
-
- final_env = dict(deploy_defaults.items() +
- deploy_params.items() +
- user_env.items())
+ # Create a tempdir for this deployment to work in
+ deploy_tempdir = tempfile.mkdtemp(
+ dir=os.path.join(self.app.settings['tempdir'], 'deployments'))
+ try:
+ for system in cluster_morphology['systems']:
+ self.deploy_system(build_command, deploy_tempdir,
+ root_repo_dir, bb.root_repo_url,
+ bb.root_ref, system, env_vars,
+ parent_location='')
+ finally:
+ shutil.rmtree(deploy_tempdir)
- is_upgrade = 'yes' if self.app.settings['upgrade'] else 'no'
- final_env['UPGRADE'] = is_upgrade
-
- deployment_type = final_env.pop('type', None)
- if not deployment_type:
- raise morphlib.Error('"type" is undefined '
- 'for system "%s"' % system_id)
-
- location = final_env.pop('location', None)
- if not location:
- raise morphlib.Error('"location" is undefined '
- 'for system "%s"' % system_id)
+ self.app.status(msg='Finished deployment')
- morphlib.util.sanitize_environment(final_env)
- self.do_deploy(build_command, root_repo_dir, ref, artifact,
- deployment_type, location, final_env)
+ def deploy_system(self, build_command, deploy_tempdir,
+ root_repo_dir, build_repo, ref, system, env_vars,
+ parent_location):
+ old_status_prefix = self.app.status_prefix
+ system_status_prefix = '%s[%s]' % (old_status_prefix, system['morph'])
+ self.app.status_prefix = system_status_prefix
+ try:
+ # Find the artifact to build
+ morph = system['morph']
+ srcpool = build_command.create_source_pool(build_repo, ref,
+ morph + '.morph')
+
+ artifact = build_command.resolve_artifacts(srcpool)
+
+ deploy_defaults = system.get('deploy-defaults', {})
+ deployments = system['deploy']
+ for system_id, deploy_params in deployments.iteritems():
+ deployment_status_prefix = '%s[%s]' % (
+ system_status_prefix, system_id)
+ self.app.status_prefix = deployment_status_prefix
+ try:
+ user_env = morphlib.util.parse_environment_pairs(
+ os.environ,
+ [pair[len(system_id)+1:]
+ for pair in env_vars
+ if pair.startswith(system_id)])
+
+ final_env = dict(deploy_defaults.items() +
+ deploy_params.items() +
+ user_env.items())
+
+ is_upgrade = ('yes' if self.app.settings['upgrade']
+ else 'no')
+ final_env['UPGRADE'] = is_upgrade
+
+ deployment_type = final_env.pop('type', None)
+ if not deployment_type:
+ raise morphlib.Error('"type" is undefined '
+ 'for system "%s"' % system_id)
+
+ location = final_env.pop('location', None)
+ if not location:
+ raise morphlib.Error('"location" is undefined '
+ 'for system "%s"' % system_id)
+
+ morphlib.util.sanitize_environment(final_env)
+ self.check_deploy(root_repo_dir, ref, deployment_type,
+ location, final_env)
+ system_tree = self.setup_deploy(build_command,
+ deploy_tempdir,
+ root_repo_dir,
+ ref, artifact,
+ deployment_type,
+ location, final_env)
+ for subsystem in system.get('subsystems', []):
+ self.deploy_system(build_command, deploy_tempdir,
+ root_repo_dir, build_repo,
+ ref, subsystem, env_vars,
+ parent_location=system_tree)
+ if parent_location:
+ deploy_location = os.path.join(parent_location,
+ location.lstrip('/'))
+ else:
+ deploy_location = location
+ self.run_deploy_commands(deploy_tempdir, final_env,
+ artifact, root_repo_dir,
+ ref, deployment_type,
+ system_tree, deploy_location)
+ finally:
+ self.app.status_prefix = system_status_prefix
+ finally:
+ self.app.status_prefix = old_status_prefix
- def do_deploy(self, build_command, root_repo_dir, ref, artifact,
- deployment_type, location, env):
+ def check_deploy(self, root_repo_dir, ref, deployment_type, location, env):
# Run optional write check extension. These are separate from the write
# extension because it may be several minutes before the write
# extension itself has the chance to raise an error.
@@ -396,18 +430,14 @@ class DeployPlugin(cliapp.Plugin):
except ExtensionNotFoundError:
pass
- # Create a tempdir for this deployment to work in
- deploy_tempdir = tempfile.mkdtemp(
- dir=os.path.join(self.app.settings['tempdir'], 'deployments'))
- try:
- # Create a tempdir to extract the rootfs in
- system_tree = tempfile.mkdtemp(dir=deploy_tempdir)
+ def setup_deploy(self, build_command, deploy_tempdir, root_repo_dir, ref,
+ artifact, deployment_type, location, env):
+ # deployment_type, location and env are only used for saving metadata
- # Extensions get a private tempdir so we can more easily clean
- # up any files an extension left behind
- deploy_private_tempdir = tempfile.mkdtemp(dir=deploy_tempdir)
- env['TMPDIR'] = deploy_private_tempdir
+ # Create a tempdir to extract the rootfs in
+ system_tree = tempfile.mkdtemp(dir=deploy_tempdir)
+ try:
# Unpack the artifact (tarball) to a temporary directory.
self.app.status(msg='Unpacking system for configuration')
@@ -435,7 +465,19 @@ class DeployPlugin(cliapp.Plugin):
system_tree, 'baserock', 'deployment.meta')
with morphlib.savefile.SaveFile(metadata_path, 'w') as f:
f.write(json.dumps(metadata, indent=4, sort_keys=True))
+ return system_tree
+ except Exception:
+ shutil.rmtree(system_tree)
+ raise
+
+ def run_deploy_commands(self, deploy_tempdir, env, artifact, root_repo_dir,
+ ref, deployment_type, system_tree, location):
+ # Extensions get a private tempdir so we can more easily clean
+ # up any files an extension left behind
+ deploy_private_tempdir = tempfile.mkdtemp(dir=deploy_tempdir)
+ env['TMPDIR'] = deploy_private_tempdir
+ try:
# Run configuration extensions.
self.app.status(msg='Configure system')
names = artifact.source.morphology['configuration-extensions']
@@ -461,9 +503,7 @@ class DeployPlugin(cliapp.Plugin):
finally:
# Cleanup.
self.app.status(msg='Cleaning up')
- shutil.rmtree(deploy_tempdir)
-
- self.app.status(msg='Finished deployment')
+ shutil.rmtree(deploy_private_tempdir)
def _run_extension(self, gd, ref, name, kind, args, env):
'''Run an extension.
@@ -502,7 +542,8 @@ class DeployPlugin(cliapp.Plugin):
name=name, kind=kind)
self.app.runcmd(
[ext_filename] + args,
- ['sh', '-c', 'while read l; do echo `date "+%F %T"` $l; done'],
+ ['sh', '-c', 'while read l; do echo `date "+%F %T"` "$1$l"; done',
+ '-', '%s[%s]' % (self.app.status_prefix, name + kind)],
cwd=gd.dirname, env=env, stdout=None, stderr=None)
if delete_ext:
diff --git a/morphlib/stagingarea_tests.py b/morphlib/stagingarea_tests.py
index 1c424ab8..52f495eb 100644
--- a/morphlib/stagingarea_tests.py
+++ b/morphlib/stagingarea_tests.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2013 Codethink Limited
+# Copyright (C) 2012-2014 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
diff --git a/scripts/edit-morph b/scripts/edit-morph
index 2970cc6e..465a3ea3 100755
--- a/scripts/edit-morph
+++ b/scripts/edit-morph
@@ -16,6 +16,7 @@
import cliapp
+import contextlib
import os
import re
import yaml
@@ -201,6 +202,15 @@ class EditMorph(cliapp.Application):
return result
+ @staticmethod
+ @contextlib.contextmanager
+ def _open_yaml(path):
+ with open(path, 'r') as f:
+ d = yaml.load(f)
+ yield d
+ with open(path, 'w') as f:
+ yaml.dump(d, f)
+
def cmd_set_system_artifact_depends(self, args):
'''Change the artifacts used by a System.
@@ -219,13 +229,10 @@ class EditMorph(cliapp.Application):
file_path = args[0]
stratum_name = args[1]
artifacts = re.split(r"\s+and\s+|,?\s*", args[2])
- with open(file_path, "r") as f:
- d = yaml.load(f)
- for spec in d["strata"]:
- if spec.get("alias", spec["name"]) == stratum_name:
- spec["artifacts"] = artifacts
- with open(file_path, "w") as f:
- yaml.dump(d, f)
+ with self._open_yaml(file_path) as d:
+ for spec in d["strata"]:
+ if spec.get("alias", spec["name"]) == stratum_name:
+ spec["artifacts"] = artifacts
def cmd_set_stratum_match_rules(self, (file_path, match_rules)):
'''Set a stratum's match rules.
@@ -239,10 +246,89 @@ class EditMorph(cliapp.Application):
The match rules must be a string that yaml can parse.
'''
- with open(file_path, "r") as f:
- d = yaml.load(f)
- d['products'] = yaml.load(match_rules)
- with open(file_path, "w") as f:
+ with self._open_yaml(file_path) as d:
+ d['products'] = yaml.load(match_rules)
+
+ @classmethod
+ def _splice_cluster_system(cls, syslist, syspath):
+ sysname = syspath[0]
+ syspath = syspath[1:]
+ for system in syslist:
+ if sysname in system['deploy']:
+ break
+ else:
+ system = {
+ 'morph': None,
+ 'deploy': {
+ sysname: {
+ 'type': None,
+ 'location': None,
+ },
+ },
+ }
+ syslist.append(system)
+ if syspath:
+ cls._splice_cluster_system(
+ system.setdefault('subsystems', []), syspath)
+
+ @classmethod
+ def _find_cluster_system(cls, syslist, syspath):
+ sysname = syspath[0]
+ syspath = syspath[1:]
+ for system in syslist:
+ if sysname in system['deploy']:
+ break
+ if syspath:
+ return cls._find_cluster_system(system['subsystems'], syspath)
+ return system
+
+ def cmd_cluster_init(self, (cluster_file,)):
+ suffix = '.morph'
+ if not cluster_file.endswith(suffix):
+ raise cliapp.AppException(
+ "Morphology file path must end with .morph")
+ with open(cluster_file, 'w') as f:
+ d = {
+ 'name': os.path.basename(cluster_file)[:-len(suffix)],
+ 'kind': 'cluster',
+ }
yaml.dump(d, f)
+ def cmd_cluster_system_init(self, (cluster_file, system_path)):
+ syspath = system_path.split('.')
+ with self._open_yaml(cluster_file) as d:
+ self._splice_cluster_system(d.setdefault('systems', []), syspath)
+
+ def cmd_cluster_system_set_morphology(self,
+ (cluster_file, system_path, morphology)):
+
+ syspath = system_path.split('.')
+ with self._open_yaml(cluster_file) as d:
+ system = self._find_cluster_system(d['systems'], syspath)
+ system['morph'] = morphology
+
+ def cmd_cluster_system_set_deploy_type(self,
+ (cluster_file, system_path, deploy_type)):
+
+ syspath = system_path.split('.')
+ with self._open_yaml(cluster_file) as d:
+ system = self._find_cluster_system(d['systems'], syspath)
+ system['deploy'][syspath[-1]]['type'] = deploy_type
+
+ def cmd_cluster_system_set_deploy_location(self,
+ (cluster_file, system_path, deploy_location)):
+
+ syspath = system_path.split('.')
+ with self._open_yaml(cluster_file) as d:
+ system = self._find_cluster_system(d['systems'], syspath)
+ system['deploy'][syspath[-1]]['location'] = deploy_location
+
+ def cmd_cluster_system_set_deploy_variable(self,
+ (cluster_file, system_path, key, val)):
+
+ syspath = system_path.split('.')
+ with self._open_yaml(cluster_file) as d:
+ system = self._find_cluster_system(d['systems'], syspath)
+ system['deploy'][syspath[-1]][key] = val
+
EditMorph().run()
diff --git a/tests.as-root/rootfs-tarball-builds-rootfs-and-kernel.script b/tests.as-root/rootfs-tarball-builds-rootfs-and-kernel.script
index 93cd135f..20b61507 100755
--- a/tests.as-root/rootfs-tarball-builds-rootfs-and-kernel.script
+++ b/tests.as-root/rootfs-tarball-builds-rootfs-and-kernel.script
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (C) 2011, 2012, 2013 Codethink Limited
+# Copyright (C) 2011, 2012, 2013, 2014 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
diff --git a/tests.merging/setup b/tests.merging/setup
index 2fdf9db0..411fc45d 100755
--- a/tests.merging/setup
+++ b/tests.merging/setup
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright (C) 2012-2013 Codethink Limited
+# Copyright (C) 2012-2014 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
diff --git a/yarns/deployment.yarn b/yarns/deployment.yarn
index f98d2751..a5da8ee5 100644
--- a/yarns/deployment.yarn
+++ b/yarns/deployment.yarn
@@ -13,9 +13,13 @@ Morph Deployment Tests
GIVEN a workspace
AND a git server
WHEN the user checks out the system branch called master
- GIVEN a cluster called test-cluster for deploying only the test-system system as type tar in system branch master
+ GIVEN a cluster called test-cluster in system branch master
+ AND a system in cluster test-cluster in branch master called test-system
+ AND system test-system in cluster test-cluster in branch master builds test-system
+ AND system test-system in cluster test-cluster in branch master has deployment type: tar
+ AND system test-system in cluster test-cluster in branch master has deployment location: test.tar
WHEN the user builds the system test-system in branch master
- AND the user attempts to deploy the cluster test-cluster in branch master with options system.location=test.tar
+ AND the user attempts to deploy the cluster test-cluster in branch master
THEN morph succeeded
Some deployment types support upgrades, but some do not and Morph needs to make
@@ -25,9 +29,13 @@ this clear.
GIVEN a workspace
AND a git server
WHEN the user checks out the system branch called master
- GIVEN a cluster called test-cluster for deploying only the test-system system as type tar in system branch master
+ GIVEN a cluster called test-cluster in system branch master
+ AND a system in cluster test-cluster in branch master called test-system
+ AND system test-system in cluster test-cluster in branch master builds test-system
+ AND system test-system in cluster test-cluster in branch master has deployment type: tar
+ AND system test-system in cluster test-cluster in branch master has deployment location: test.tar
WHEN the user builds the system test-system in branch master
- AND the user attempts to upgrade the cluster test-cluster in branch master with options system.location=test.tar
+ AND the user attempts to upgrade the cluster test-cluster in branch master
THEN morph failed
The rawdisk write extension supports both initial deployment and subsequent
@@ -40,8 +48,57 @@ the same code paths as a real upgrade.
GIVEN a workspace
AND a git server
WHEN the user checks out the system branch called master
- GIVEN a cluster called test-cluster for deploying only the test-system system as type rawdisk in system branch master
+ GIVEN a cluster called test-cluster in system branch master
+ AND a system in cluster test-cluster in branch master called test-system
+ AND system test-system in cluster test-cluster in branch master builds test-system
+ AND system test-system in cluster test-cluster in branch master has deployment type: rawdisk
+ AND system test-system in cluster test-cluster in branch master has deployment location: test.tar
WHEN the user builds the system test-system in branch master
- AND the user attempts to deploy the cluster test-cluster in branch master with options system.location=test.img system.DISK_SIZE=10M system.VERSION_LABEL=test1
- AND the user attempts to upgrade the cluster test-cluster in branch master with options system.location=test.img system.VERSION_LABEL=test2
+ AND the user attempts to deploy the cluster test-cluster in branch master with options test-system.DISK_SIZE=10M test-system.VERSION_LABEL=test1
THEN morph succeeded
+ WHEN the user attempts to upgrade the cluster test-cluster in branch master with options test-system.VERSION_LABEL=test2
+ THEN morph succeeded
+
+Nested deployments
+==================
+
+For the use-cases of:
+
+1. Installer CD/USB
+2. NFS/VM host
+3. System with multiple containerised applications
+4. System with a toolchain targetting the sysroot of another target
+5. Any nested combination of the above
+
+It is convenient to be able to deploy one system inside another.
+
+ SCENARIO deploying a cluster morphology with nested systems
+ GIVEN a workspace
+ AND a git server
+ WHEN the user checks out the system branch called master
+ GIVEN a cluster called test-cluster in system branch master
+ AND a system in cluster test-cluster in branch master called test-system
+ AND system test-system in cluster test-cluster in branch master builds test-system
+ AND system test-system in cluster test-cluster in branch master has deployment type: tar
+
+After the usual setup, we also add a subsystem to the cluster.
+
+ GIVEN a subsystem in cluster test-cluster in branch master called test-system.sysroot
+ AND subsystem test-system.sysroot in cluster test-cluster in branch master builds test-system
+ AND subsystem test-system.sysroot in cluster test-cluster in branch master has deployment type: sysroot
+
+We specify the location as a file path, this is relative to the parent
+system's extracted rootfs, before it is configured.
+
+ AND subsystem test-system.sysroot in cluster test-cluster in branch master has deployment location: var/lib/sysroots/test-system
+ WHEN the user builds the system test-system in branch master
+ AND the user attempts to deploy the cluster test-cluster in branch master with options test-system.location="$DATADIR/test.tar"
+ THEN morph succeeded
+
+Morph succeeding alone is not sufficient to check whether it actually
+worked, since if it ignored the subsystems field, or got the location
+wrong for the subsystem. To actually test it, we have to check that our
+deployed system contains the other. Since the baserock directory is in
+every system, we can check for that.
+
+ AND tarball test.tar contains var/lib/sysroots/test-system/baserock
diff --git a/yarns/implementations.yarn b/yarns/implementations.yarn
index 3e5b3ab5..e4f36399 100644
--- a/yarns/implementations.yarn
+++ b/yarns/implementations.yarn
@@ -675,27 +675,6 @@ them, so they can be added to the end of the implements section.
if [ $MATCH_1 == "upgrades" ]; then run_morph "$@"
else attempt_morph "$@"; fi
-To successfully deploy systems, we need a cluster morphology. Since the
-common case is to just have one system, we generate a stub morphology
-with only the minimal information.
-
- IMPLEMENTS GIVEN a cluster called (\S+) for deploying only the (\S+) system as type (\S+) in system branch (\S+)
- name="$MATCH_1"
- system="$MATCH_2"
- type="$MATCH_3"
- branch="$MATCH_4"
- cat << EOF > "$DATADIR/workspace/$branch/test/morphs/$name.morph"
- name: $name
- kind: cluster
- systems:
- - morph: $system
- repo: test:morphs
- ref: $branch
- deploy:
- system:
- type: $type
- EOF
-
Implementations sections for reading error messages
===================================================
@@ -817,7 +796,61 @@ Altering morphologies in their source repositories
Altering morphologies in the workspace
--------------------------------------
+### Altering strata ###
+
IMPLEMENTS GIVEN stratum (\S+) in system branch (\S+) has match rules: (.*)
cd "$DATADIR/workspace/$MATCH_2/test/morphs"
"$SRCDIR/scripts/edit-morph" set-stratum-match-rules \
"$MATCH_1.morph" "$MATCH_3"
+
+### Altering clusters ###
+
+ IMPLEMENTS GIVEN a cluster called (\S+) in system branch (\S+)
+ name="$MATCH_1"
+ branch="$MATCH_2"
+ "$SRCDIR/scripts/edit-morph" cluster-init \
+ "$DATADIR/workspace/$branch/test/morphs/$name.morph"
+
+ IMPLEMENTS GIVEN a (sub)?system in cluster (\S+) in branch (\S+) called (\S+)
+ cluster="$MATCH_2"
+ branch="$MATCH_3"
+ name="$MATCH_4"
+ "$SRCDIR/scripts/edit-morph" cluster-system-init \
+ "$DATADIR/workspace/$branch/test/morphs/$cluster.morph" "$name"
+
+ IMPLEMENTS GIVEN (sub)?system (\S+) in cluster (\S+) in branch (\S+) builds (\S+)
+ name="$MATCH_2"
+ cluster="$MATCH_3"
+ branch="$MATCH_4"
+ morphology="$MATCH_5"
+ "$SRCDIR/scripts/edit-morph" cluster-system-set-morphology \
+ "$DATADIR/workspace/$branch/test/morphs/$cluster.morph" "$name" \
+ "$morphology"
+
+ IMPLEMENTS GIVEN (sub)?system (\S+) in cluster (\S+) in branch (\S+) has deployment type: (\S+)
+ name="$MATCH_2"
+ cluster="$MATCH_3"
+ branch="$MATCH_4"
+ type="$MATCH_5"
+ "$SRCDIR/scripts/edit-morph" cluster-system-set-deploy-type \
+ "$DATADIR/workspace/$branch/test/morphs/$cluster.morph" "$name" \
+ "$type"
+
+ IMPLEMENTS GIVEN (sub)?system (\S+) in cluster (\S+) in branch (\S+) has deployment location: (\S+)
+ name="$MATCH_2"
+ cluster="$MATCH_3"
+ branch="$MATCH_4"
+ location="$MATCH_5"
+ "$SRCDIR/scripts/edit-morph" cluster-system-set-deploy-location \
+ "$DATADIR/workspace/$branch/test/morphs/$cluster.morph" "$name" \
+ "$location"
+
+ IMPLEMENTS GIVEN (sub)?system (\S+) in cluster (\S+) in branch (\S+) has deployment variable: ([^=]+)=(.*)
+ name="$MATCH_2"
+ cluster="$MATCH_3"
+ branch="$MATCH_4"
+ key="$MATCH_5"
+ val="$MATCH_6"
+ "$SRCDIR/scripts/edit-morph" cluster-system-set-deploy-variable \
+ "$DATADIR/workspace/$branch/test/morphs/$cluster.morph" "$name" \
+ "$key" "$val"
diff --git a/yarns/regression.yarn b/yarns/regression.yarn
index d8eedea2..b0f4d112 100644
--- a/yarns/regression.yarn
+++ b/yarns/regression.yarn
@@ -58,11 +58,14 @@ source it depended on.
AND system test-system uses test-stratum-runtime from test-stratum
AND stratum test-stratum has match rules: [{artifact: test-stratum-runtime, include: [.*-(bins|libs|locale)]}, {artifact: test-stratum-devel, include: [.*-(devel|doc|misc)]}]
WHEN the user checks out the system branch called master
- GIVEN a cluster called test-cluster for deploying only the test-system system as type tar in system branch master
+ GIVEN a cluster called test-cluster in system branch master
+ AND a system in cluster test-cluster in branch master called test-system
+ AND system test-system in cluster test-cluster in branch master builds test-system
+ AND system test-system in cluster test-cluster in branch master has deployment type: tar
WHEN the user builds the system test-system in branch master
GIVEN stratum test-stratum in system branch master has match rules: [{artifact: test-stratum-runtime, include: [.*-(bins|libs|misc)]}, {artifact: test-stratum-devel, include: [.*-(devel|doc|locale)]}]
WHEN the user builds the system test-system in branch master
- AND the user deploys the cluster test-cluster in branch master with options system.location="$DATADIR/test.tar"
+ AND the user deploys the cluster test-cluster in branch master with options test-system.location="$DATADIR/test.tar"
THEN tarball test.tar contains baserock/test-chunk-misc.meta
diff --git a/yarns/splitting.yarn b/yarns/splitting.yarn
index 3da397f5..ee587e11 100644
--- a/yarns/splitting.yarn
+++ b/yarns/splitting.yarn
@@ -47,9 +47,12 @@ The best way to test that only using some stratum artifacts works is
to check which files the output has, so we deploy a tarball and inspect
its contents.
- GIVEN a cluster called test-cluster for deploying only the test-system system as type tar in system branch master
+ GIVEN a cluster called test-cluster in system branch master
+ AND a system in cluster test-cluster in branch master called test-system
+ AND system test-system in cluster test-cluster in branch master builds test-system
+ AND system test-system in cluster test-cluster in branch master has deployment type: tar
WHEN the user builds the system test-system in branch master
- AND the user attempts to deploy the cluster test-cluster in branch master with options system.location="$DATADIR/test.tar"
+ AND the user attempts to deploy the cluster test-cluster in branch master with options test-system.location="$DATADIR/test.tar"
The -runtime artifacts include executables and shared libraries.