summaryrefslogtreecommitdiff
path: root/morphlib/plugins/deploy_plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'morphlib/plugins/deploy_plugin.py')
-rw-r--r--morphlib/plugins/deploy_plugin.py117
1 files changed, 93 insertions, 24 deletions
diff --git a/morphlib/plugins/deploy_plugin.py b/morphlib/plugins/deploy_plugin.py
index e795e637..7635a7b4 100644
--- a/morphlib/plugins/deploy_plugin.py
+++ b/morphlib/plugins/deploy_plugin.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2013, 2014 Codethink Limited
+# Copyright (C) 2013-2015 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
@@ -10,8 +10,7 @@
# 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.
+# with this program. If not, see <http://www.gnu.org/licenses/>.
import json
@@ -124,7 +123,7 @@ class DeployPlugin(cliapp.Plugin):
Each system defined in a cluster morphology can be deployed in
multiple ways (`type` in a cluster morphology). Morph provides
- five types of deployment:
+ the following types of deployment:
* `tar` where Morph builds a tar archive of the root file system.
@@ -144,6 +143,35 @@ class DeployPlugin(cliapp.Plugin):
* `nfsboot` where Morph creates a system to be booted over
a network.
+ * `ssh-rsync` where Morph copies a binary delta over to the target
+ system and arranges for it to be bootable. This requires
+ `system-version-manager` from the tbdiff chunk
+
+ * `initramfs`, where Morph turns the system into an initramfs image,
+ suitable for being used as the early userland environment for a
+ system to be able to locate more complicated storage for its root
+ file-system, or on its own for diskless deployments.
+
+ There are additional extensions that currently live in the Baserock
+ definitions repo (baserock:baserock/definitions). These include:
+
+ * `image-package` where Morph creates a tarball that includes scripts
+ that can be used to make disk images outside of a Baserock
+ environment. The example in definitions.git will create scripts for
+ generating disk images and installing to existing disks.
+
+ * `sdk` where Morph generates something resembing a BitBake SDK, which
+ provides a toolchain for building software to target a system built
+ by Baserock, from outside of a Baserock environment. This creates a
+ self-extracting shell archive which you pass a directory to extract
+ to, and inside that has a shell snippet called
+ environment-setup-$TARGET which can be used to set environment
+ variables to use the toolchain.
+
+ * `pxeboot` where Morph temporarily network-boots the system you are
+ deploying, so it can install a more permanent system onto local
+ storage.
+
In addition to the deployment type, the user must also give
a value for `location`. Its syntax depends on the deployment
types. The deployment types provided by Morph use the
@@ -177,6 +205,31 @@ class DeployPlugin(cliapp.Plugin):
the _address_ of the trove, _not_ `user@...`, since `root@` will
automatically be prepended to the server address.)
+ In addition to the `location`parameter, deployments can take additional
+ `KEY=VALUE` parameters. These can be provided in the following ways:
+
+ 1. In the cluster definition file, e.g.
+
+ ...
+ systems:
+ - morph: systems/foo-system.morph
+ deploy:
+ foo:
+ HOSTNAME: foo
+
+ 2. In the environment before running e.g.
+
+ `HOSTNAME=foo morph deploy ...`
+
+ 3. On the command-line e.g.
+ `morph deploy clusters/foo.morph foo.HOSTNAME=foo`
+
+ For any boolean `KEY=VALUE` parameters, allowed values are:
+
+ +ve `yes`, `1`, `true`;
+
+ -ve `no`, `0`, `false`;
+
The following `KEY=VALUE` parameters are supported for `rawdisk`,
`virtualbox-ssh` and `kvm` and deployment types:
@@ -281,12 +334,12 @@ class DeployPlugin(cliapp.Plugin):
self.app.settings['tempdir-min-space'],
'/', 0)
- self.app.settings['no-git-update'] = True
- cluster_filename = morphlib.util.sanitise_morphology_path(args[0])
-
ws = morphlib.workspace.open('.')
sb = morphlib.sysbranchdir.open_from_within('.')
+ cluster_filename = morphlib.util.sanitise_morphology_path(args[0])
+ cluster_filename = sb.relative_to_root_repo(cluster_filename)
+
build_uuid = uuid.uuid4().hex
build_command = morphlib.buildcommand.BuildCommand(self.app)
@@ -298,6 +351,7 @@ class DeployPlugin(cliapp.Plugin):
build_ref_prefix = self.app.settings['build-ref-prefix']
root_repo_dir = morphlib.gitdir.GitDirectory(
sb.get_git_directory_name(sb.root_repository_url))
+
cluster_text = root_repo_dir.read_file(cluster_filename)
cluster_morphology = loader.load_from_string(cluster_text,
filename=cluster_filename)
@@ -323,23 +377,24 @@ class DeployPlugin(cliapp.Plugin):
self.validate_deployment_options(
env_vars, all_deployments, all_subsystems)
- bb = morphlib.buildbranch.BuildBranch(sb, build_ref_prefix)
- pbb = morphlib.buildbranch.pushed_build_branch(
- bb, loader=loader, changes_need_pushing=False,
- name=name, email=email, build_uuid=build_uuid,
- status=self.app.status)
- with pbb as (repo, commit, original_ref):
- # 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, repo, commit, system,
- env_vars, deployments,
- parent_location='')
- finally:
- shutil.rmtree(deploy_tempdir)
+ if self.app.settings['local-changes'] == 'include':
+ bb = morphlib.buildbranch.BuildBranch(sb, build_ref_prefix)
+ pbb = morphlib.buildbranch.pushed_build_branch(
+ bb, loader=loader, changes_need_pushing=False,
+ name=name, email=email, build_uuid=build_uuid,
+ status=self.app.status)
+ with pbb as (repo, commit, original_ref):
+ self.deploy_cluster(build_command, cluster_morphology,
+ root_repo_dir, repo, commit, env_vars,
+ deployments)
+ else:
+ repo = sb.get_config('branch.root')
+ ref = sb.get_config('branch.name')
+ commit = root_repo_dir.resolve_ref_to_commit(ref)
+
+ self.deploy_cluster(build_command, cluster_morphology,
+ root_repo_dir, repo, commit, env_vars,
+ deployments)
self.app.status(msg='Finished deployment')
@@ -359,6 +414,20 @@ class DeployPlugin(cliapp.Plugin):
'Variable referenced a non-existent deployment '
'name: %s' % var)
+ def deploy_cluster(self, build_command, cluster_morphology, root_repo_dir,
+ repo, commit, env_vars, deployments):
+ # 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, repo, commit, system,
+ env_vars, deployments,
+ parent_location='')
+ finally:
+ shutil.rmtree(deploy_tempdir)
+
def deploy_system(self, build_command, deploy_tempdir,
root_repo_dir, build_repo, ref, system, env_vars,
deployment_filter, parent_location):