diff options
Diffstat (limited to 'morphlib/plugins/deploy_plugin.py')
-rw-r--r-- | morphlib/plugins/deploy_plugin.py | 117 |
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): |