From 03d342985364b03f61c0b47df6e598ea8ccb49ff Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Fri, 1 May 2015 21:34:06 +0000 Subject: Use DefinitionsRepo class in deploy plugin This allows you to run `morph deploy` from any Git checkout of definitions.git. Change-Id: I64c48f59c8ec5aebc7169f3b4b4abbb759bd0b9a --- morphlib/plugins/deploy_plugin.py | 120 ++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 70 deletions(-) diff --git a/morphlib/plugins/deploy_plugin.py b/morphlib/plugins/deploy_plugin.py index 0e4f32f9..a5eabe03 100644 --- a/morphlib/plugins/deploy_plugin.py +++ b/morphlib/plugins/deploy_plugin.py @@ -21,7 +21,6 @@ import shutil import sys import tarfile import tempfile -import uuid import warnings import cliapp @@ -326,25 +325,14 @@ class DeployPlugin(cliapp.Plugin): self.app.settings['tempdir-min-space'], '/', 0) - ws = morphlib.workspace.open('.') - sb = morphlib.sysbranchdir.open_from_within('.') + definitions_repo = morphlib.definitions_repo.open( + '.', search_for_root=True, search_workspace=True, app=self.app) cluster_filename = morphlib.util.sanitise_morphology_path(args[0]) - cluster_filename = sb.relative_to_root_repo(cluster_filename) + cluster_filename = definitions_repo.relative_path(cluster_filename) - build_uuid = uuid.uuid4().hex - - build_command = morphlib.buildcommand.BuildCommand(self.app) - build_command = self.app.hookmgr.call('new-build-command', - build_command) loader = morphlib.morphloader.MorphologyLoader() - name = morphlib.git.get_user_name(self.app.runcmd) - email = morphlib.git.get_user_email(self.app.runcmd) - 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_text = definitions_repo.read_file(cluster_filename) cluster_morphology = loader.load_from_string(cluster_text, filename=cluster_filename) @@ -369,24 +357,8 @@ class DeployPlugin(cliapp.Plugin): self.validate_deployment_options( env_vars, all_deployments, all_subsystems) - 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(sb, 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(sb, build_command, cluster_morphology, - root_repo_dir, repo, commit, env_vars, - deployments) + self.deploy_cluster(definitions_repo, cluster_morphology, + env_vars, deployments) self.app.status(msg='Finished deployment') if self.app.settings['partial']: @@ -411,25 +383,33 @@ class DeployPlugin(cliapp.Plugin): 'Variable referenced a non-existent deployment ' 'name: %s' % var) - def deploy_cluster(self, sb, build_command, cluster_morphology, - root_repo_dir, repo, commit, env_vars, deployments): + def deploy_cluster(self, definitions_repo, cluster_morphology, + 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')) + include_local_changes = (self.app.settings['local-changes']=='include') try: + # FIXME: right now we create a temporary branch for each system, + # for system in cluster_morphology['systems']: - self.deploy_system(sb, build_command, deploy_tempdir, - root_repo_dir, repo, commit, system, - env_vars, deployments, - parent_location='') + morph = morphlib.util.sanitise_morphology_path(system['morph']) + source_pool_context = definitions_repo.source_pool( + definitions_repo.HEAD, morph, + include_local_changes=include_local_changes) + with source_pool_context as source_pool: + self.deploy_system(deploy_tempdir, definitions_repo, + source_pool, system, env_vars, + deployments, parent_location='') finally: shutil.rmtree(deploy_tempdir) - def _sanitise_morphology_paths(self, paths, sb): + def _sanitise_morphology_paths(self, paths, definitions_repo): sanitised_paths = [] for path in paths: path = morphlib.util.sanitise_morphology_path(path) - sanitised_paths.append(sb.relative_to_root_repo(path)) + sanitised_paths.append(definitions_repo.relative_path(path)) + sanitised_paths.append(path) return sanitised_paths def _find_artifacts(self, filenames, root_artifact): @@ -463,9 +443,8 @@ class DeployPlugin(cliapp.Plugin): artifact.source.name)) return components - def deploy_system(self, sb, build_command, deploy_tempdir, - root_repo_dir, build_repo, ref, system, env_vars, - deployment_filter, parent_location): + def deploy_system(self, deploy_tempdir, definitions_repo, source_pool, + system, env_vars, deployment_filter, parent_location): sys_ids = set(system['deploy'].iterkeys()) if deployment_filter and not \ any(sys_id in deployment_filter for sys_id in sys_ids): @@ -475,10 +454,10 @@ class DeployPlugin(cliapp.Plugin): self.app.status_prefix = system_status_prefix try: # Find the artifact to build - morph = morphlib.util.sanitise_morphology_path(system['morph']) - srcpool = build_command.create_source_pool(build_repo, ref, morph) + #morph = morphlib.util.sanitise_morphology_path(system['morph']) - artifact = build_command.resolve_artifacts(srcpool) + build_command = morphlib.buildcommand.BuildCommand(self.app) + artifact = build_command.resolve_artifacts(source_pool) deploy_defaults = system.get('deploy-defaults', {}) for system_id, deploy_params in system['deploy'].iteritems(): @@ -499,34 +478,34 @@ class DeployPlugin(cliapp.Plugin): system_id, final_env, self.app.settings['upgrade']) components = self._sanitise_morphology_paths( - deploy_params.get('partial-deploy-components', []), sb) + deploy_params.get('partial-deploy-components', []), + definitions_repo) if self.app.settings['partial']: components = self._validate_partial_deployment( deployment_type, artifact, components) - self.check_deploy(root_repo_dir, ref, deployment_type, + self.check_deploy(definitions_repo, deployment_type, location, final_env) system_tree = self.setup_deploy(build_command, deploy_tempdir, - root_repo_dir, - ref, artifact, + definitions_repo, + artifact, deployment_type, location, final_env, components=components) for subsystem in system.get('subsystems', []): - self.deploy_system(sb, build_command, deploy_tempdir, - root_repo_dir, build_repo, - ref, subsystem, env_vars, [], - parent_location=system_tree) + self.deploy_system(deploy_tempdir, definitions_repo, + source_pool, 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) + artifact, definitions_repo, + deployment_type, system_tree, + deploy_location) finally: self.app.status_prefix = system_status_prefix finally: @@ -576,13 +555,13 @@ class DeployPlugin(cliapp.Plugin): self.app.settings['upgrade'] = True self.deploy(args) - def check_deploy(self, root_repo_dir, ref, deployment_type, location, env): + def check_deploy(self, definitions_repo, 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. try: self._run_extension( - root_repo_dir, deployment_type, '.check', + definitions_repo, deployment_type, '.check', [location], env) except morphlib.extensions.ExtensionNotFoundError: pass @@ -710,7 +689,7 @@ class DeployPlugin(cliapp.Plugin): msg='Components %(components)s unpacked at %(path)s', components=', '.join(components), path=path) - def setup_deploy(self, build_command, deploy_tempdir, root_repo_dir, ref, + def setup_deploy(self, build_command, deploy_tempdir, definitions_repo, artifact, deployment_type, location, env, components=[]): # Create a tempdir to extract the rootfs in system_tree = tempfile.mkdtemp(dir=deploy_tempdir) @@ -725,7 +704,7 @@ class DeployPlugin(cliapp.Plugin): self.app.status( msg='Writing deployment metadata file') metadata = self.create_metadata( - artifact, root_repo_dir, deployment_type, location, env) + artifact, definitions_repo, deployment_type, location, env) metadata_path = os.path.join( system_tree, 'baserock', 'deployment.meta') with morphlib.savefile.SaveFile(metadata_path, 'w') as f: @@ -736,8 +715,9 @@ class DeployPlugin(cliapp.Plugin): shutil.rmtree(system_tree) raise - def run_deploy_commands(self, deploy_tempdir, env, artifact, root_repo_dir, - ref, deployment_type, system_tree, location): + def run_deploy_commands(self, deploy_tempdir, env, artifact, + definitions_repo, 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) @@ -750,7 +730,7 @@ class DeployPlugin(cliapp.Plugin): names = artifact.source.morphology['configuration-extensions'] for name in names: self._run_extension( - root_repo_dir, + definitions_repo, name, '.configure', [system_tree], @@ -762,7 +742,7 @@ class DeployPlugin(cliapp.Plugin): # Run write extension. self.app.status(msg='Writing to device') self._run_extension( - root_repo_dir, + definitions_repo, deployment_type, '.write', [system_tree, location], @@ -807,8 +787,8 @@ class DeployPlugin(cliapp.Plugin): name, kind, returncode, '\n'.join(error_list)) raise cliapp.AppException(message) - def create_metadata(self, system_artifact, root_repo_dir, deployment_type, - location, env, components=[]): + def create_metadata(self, system_artifact, definitions_repo, + deployment_type, location, env, components=[]): '''Deployment-specific metadata. The `build` and `deploy` operations must be from the same ref, so full @@ -832,7 +812,7 @@ class DeployPlugin(cliapp.Plugin): 'deployment-type': deployment_type, 'location': location, 'definitions-version': { - 'describe': root_repo_dir.describe(), + 'describe': definitions_repo.describe(), }, 'morph-version': { 'ref': morphlib.gitversion.ref, -- cgit v1.2.1