1eb8dc403SDave Cobbley# Development tool - deploy/undeploy command plugin 2eb8dc403SDave Cobbley# 3eb8dc403SDave Cobbley# Copyright (C) 2014-2016 Intel Corporation 4eb8dc403SDave Cobbley# 5c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only 6eb8dc403SDave Cobbley# 7eb8dc403SDave Cobbley"""Devtool plugin containing the deploy subcommands""" 8eb8dc403SDave Cobbley 9eb8dc403SDave Cobbleyimport logging 10eb8dc403SDave Cobbleyimport os 11eb8dc403SDave Cobbleyimport shutil 12eb8dc403SDave Cobbleyimport subprocess 13eb8dc403SDave Cobbleyimport tempfile 14eb8dc403SDave Cobbley 15eb8dc403SDave Cobbleyimport bb.utils 16eb8dc403SDave Cobbleyimport argparse_oe 17eb8dc403SDave Cobbleyimport oe.types 18eb8dc403SDave Cobbley 19*73bd93f1SPatrick Williamsfrom devtool import exec_fakeroot_no_d, setup_tinfoil, check_workspace_recipe, DevtoolError 20eb8dc403SDave Cobbley 21eb8dc403SDave Cobbleylogger = logging.getLogger('devtool') 22eb8dc403SDave Cobbley 23eb8dc403SDave Cobbleydeploylist_path = '/.devtool' 24eb8dc403SDave Cobbley 25eb8dc403SDave Cobbleydef _prepare_remote_script(deploy, verbose=False, dryrun=False, undeployall=False, nopreserve=False, nocheckspace=False): 26eb8dc403SDave Cobbley """ 27eb8dc403SDave Cobbley Prepare a shell script for running on the target to 28eb8dc403SDave Cobbley deploy/undeploy files. We have to be careful what we put in this 29eb8dc403SDave Cobbley script - only commands that are likely to be available on the 30eb8dc403SDave Cobbley target are suitable (the target might be constrained, e.g. using 31eb8dc403SDave Cobbley busybox rather than bash with coreutils). 32eb8dc403SDave Cobbley """ 33eb8dc403SDave Cobbley lines = [] 34eb8dc403SDave Cobbley lines.append('#!/bin/sh') 35eb8dc403SDave Cobbley lines.append('set -e') 36eb8dc403SDave Cobbley if undeployall: 37eb8dc403SDave Cobbley # Yes, I know this is crude - but it does work 38eb8dc403SDave Cobbley lines.append('for entry in %s/*.list; do' % deploylist_path) 39eb8dc403SDave Cobbley lines.append('[ ! -f $entry ] && exit') 40eb8dc403SDave Cobbley lines.append('set `basename $entry | sed "s/.list//"`') 41eb8dc403SDave Cobbley if dryrun: 42eb8dc403SDave Cobbley if not deploy: 43eb8dc403SDave Cobbley lines.append('echo "Previously deployed files for $1:"') 44eb8dc403SDave Cobbley lines.append('manifest="%s/$1.list"' % deploylist_path) 45eb8dc403SDave Cobbley lines.append('preservedir="%s/$1.preserve"' % deploylist_path) 46eb8dc403SDave Cobbley lines.append('if [ -f $manifest ] ; then') 47eb8dc403SDave Cobbley # Read manifest in reverse and delete files / remove empty dirs 48eb8dc403SDave Cobbley lines.append(' sed \'1!G;h;$!d\' $manifest | while read file') 49eb8dc403SDave Cobbley lines.append(' do') 50eb8dc403SDave Cobbley if dryrun: 51eb8dc403SDave Cobbley lines.append(' if [ ! -d $file ] ; then') 52eb8dc403SDave Cobbley lines.append(' echo $file') 53eb8dc403SDave Cobbley lines.append(' fi') 54eb8dc403SDave Cobbley else: 55eb8dc403SDave Cobbley lines.append(' if [ -d $file ] ; then') 56eb8dc403SDave Cobbley # Avoid deleting a preserved directory in case it has special perms 57eb8dc403SDave Cobbley lines.append(' if [ ! -d $preservedir/$file ] ; then') 58eb8dc403SDave Cobbley lines.append(' rmdir $file > /dev/null 2>&1 || true') 59eb8dc403SDave Cobbley lines.append(' fi') 60eb8dc403SDave Cobbley lines.append(' else') 61eb8dc403SDave Cobbley lines.append(' rm -f $file') 62eb8dc403SDave Cobbley lines.append(' fi') 63eb8dc403SDave Cobbley lines.append(' done') 64eb8dc403SDave Cobbley if not dryrun: 65eb8dc403SDave Cobbley lines.append(' rm $manifest') 66eb8dc403SDave Cobbley if not deploy and not dryrun: 67eb8dc403SDave Cobbley # May as well remove all traces 68eb8dc403SDave Cobbley lines.append(' rmdir `dirname $manifest` > /dev/null 2>&1 || true') 69eb8dc403SDave Cobbley lines.append('fi') 70eb8dc403SDave Cobbley 71eb8dc403SDave Cobbley if deploy: 72eb8dc403SDave Cobbley if not nocheckspace: 73eb8dc403SDave Cobbley # Check for available space 74eb8dc403SDave Cobbley # FIXME This doesn't take into account files spread across multiple 75eb8dc403SDave Cobbley # partitions, but doing that is non-trivial 76eb8dc403SDave Cobbley # Find the part of the destination path that exists 77eb8dc403SDave Cobbley lines.append('checkpath="$2"') 78eb8dc403SDave Cobbley lines.append('while [ "$checkpath" != "/" ] && [ ! -e $checkpath ]') 79eb8dc403SDave Cobbley lines.append('do') 80eb8dc403SDave Cobbley lines.append(' checkpath=`dirname "$checkpath"`') 81eb8dc403SDave Cobbley lines.append('done') 82eb8dc403SDave Cobbley lines.append(r'freespace=$(df -P $checkpath | sed -nre "s/^(\S+\s+){3}([0-9]+).*/\2/p")') 83eb8dc403SDave Cobbley # First line of the file is the total space 84eb8dc403SDave Cobbley lines.append('total=`head -n1 $3`') 85eb8dc403SDave Cobbley lines.append('if [ $total -gt $freespace ] ; then') 86eb8dc403SDave Cobbley lines.append(' echo "ERROR: insufficient space on target (available ${freespace}, needed ${total})"') 87eb8dc403SDave Cobbley lines.append(' exit 1') 88eb8dc403SDave Cobbley lines.append('fi') 89eb8dc403SDave Cobbley if not nopreserve: 90eb8dc403SDave Cobbley # Preserve any files that exist. Note that this will add to the 91eb8dc403SDave Cobbley # preserved list with successive deployments if the list of files 92eb8dc403SDave Cobbley # deployed changes, but because we've deleted any previously 93eb8dc403SDave Cobbley # deployed files at this point it will never preserve anything 94eb8dc403SDave Cobbley # that was deployed, only files that existed prior to any deploying 95eb8dc403SDave Cobbley # (which makes the most sense) 96eb8dc403SDave Cobbley lines.append('cat $3 | sed "1d" | while read file fsize') 97eb8dc403SDave Cobbley lines.append('do') 98eb8dc403SDave Cobbley lines.append(' if [ -e $file ] ; then') 99eb8dc403SDave Cobbley lines.append(' dest="$preservedir/$file"') 100eb8dc403SDave Cobbley lines.append(' mkdir -p `dirname $dest`') 101eb8dc403SDave Cobbley lines.append(' mv $file $dest') 102eb8dc403SDave Cobbley lines.append(' fi') 103eb8dc403SDave Cobbley lines.append('done') 104eb8dc403SDave Cobbley lines.append('rm $3') 105eb8dc403SDave Cobbley lines.append('mkdir -p `dirname $manifest`') 106eb8dc403SDave Cobbley lines.append('mkdir -p $2') 107eb8dc403SDave Cobbley if verbose: 108eb8dc403SDave Cobbley lines.append(' tar xv -C $2 -f - | tee $manifest') 109eb8dc403SDave Cobbley else: 110eb8dc403SDave Cobbley lines.append(' tar xv -C $2 -f - > $manifest') 111eb8dc403SDave Cobbley lines.append('sed -i "s!^./!$2!" $manifest') 112eb8dc403SDave Cobbley elif not dryrun: 113eb8dc403SDave Cobbley # Put any preserved files back 114eb8dc403SDave Cobbley lines.append('if [ -d $preservedir ] ; then') 115eb8dc403SDave Cobbley lines.append(' cd $preservedir') 116eb8dc403SDave Cobbley # find from busybox might not have -exec, so we don't use that 117eb8dc403SDave Cobbley lines.append(' find . -type f | while read file') 118eb8dc403SDave Cobbley lines.append(' do') 119eb8dc403SDave Cobbley lines.append(' mv $file /$file') 120eb8dc403SDave Cobbley lines.append(' done') 121eb8dc403SDave Cobbley lines.append(' cd /') 122eb8dc403SDave Cobbley lines.append(' rm -rf $preservedir') 123eb8dc403SDave Cobbley lines.append('fi') 124eb8dc403SDave Cobbley 125eb8dc403SDave Cobbley if undeployall: 126eb8dc403SDave Cobbley if not dryrun: 127eb8dc403SDave Cobbley lines.append('echo "NOTE: Successfully undeployed $1"') 128eb8dc403SDave Cobbley lines.append('done') 129eb8dc403SDave Cobbley 130eb8dc403SDave Cobbley # Delete the script itself 131eb8dc403SDave Cobbley lines.append('rm $0') 132eb8dc403SDave Cobbley lines.append('') 133eb8dc403SDave Cobbley 134eb8dc403SDave Cobbley return '\n'.join(lines) 135eb8dc403SDave Cobbley 136eb8dc403SDave Cobbleydef deploy(args, config, basepath, workspace): 137eb8dc403SDave Cobbley """Entry point for the devtool 'deploy' subcommand""" 138169d7bccSPatrick Williams import oe.utils 139eb8dc403SDave Cobbley 140eb8dc403SDave Cobbley check_workspace_recipe(workspace, args.recipename, checksrc=False) 141eb8dc403SDave Cobbley 142*73bd93f1SPatrick Williams tinfoil = setup_tinfoil(basepath=basepath) 143*73bd93f1SPatrick Williams try: 144*73bd93f1SPatrick Williams try: 145*73bd93f1SPatrick Williams rd = tinfoil.parse_recipe(args.recipename) 146*73bd93f1SPatrick Williams except Exception as e: 147*73bd93f1SPatrick Williams raise DevtoolError('Exception parsing recipe %s: %s' % 148*73bd93f1SPatrick Williams (args.recipename, e)) 149*73bd93f1SPatrick Williams 150*73bd93f1SPatrick Williams srcdir = rd.getVar('D') 151*73bd93f1SPatrick Williams workdir = rd.getVar('WORKDIR') 152*73bd93f1SPatrick Williams path = rd.getVar('PATH') 153*73bd93f1SPatrick Williams strip_cmd = rd.getVar('STRIP') 154*73bd93f1SPatrick Williams libdir = rd.getVar('libdir') 155*73bd93f1SPatrick Williams base_libdir = rd.getVar('base_libdir') 156*73bd93f1SPatrick Williams max_process = oe.utils.get_bb_number_threads(rd) 157*73bd93f1SPatrick Williams fakerootcmd = rd.getVar('FAKEROOTCMD') 158*73bd93f1SPatrick Williams fakerootenv = rd.getVar('FAKEROOTENV') 159*73bd93f1SPatrick Williams finally: 160*73bd93f1SPatrick Williams tinfoil.shutdown() 161*73bd93f1SPatrick Williams 162*73bd93f1SPatrick Williams return deploy_no_d(srcdir, workdir, path, strip_cmd, libdir, base_libdir, max_process, fakerootcmd, fakerootenv, args) 163*73bd93f1SPatrick Williams 164*73bd93f1SPatrick Williamsdef deploy_no_d(srcdir, workdir, path, strip_cmd, libdir, base_libdir, max_process, fakerootcmd, fakerootenv, args): 165*73bd93f1SPatrick Williams import math 166*73bd93f1SPatrick Williams import oe.package 167*73bd93f1SPatrick Williams 168eb8dc403SDave Cobbley try: 169eb8dc403SDave Cobbley host, destdir = args.target.split(':') 170eb8dc403SDave Cobbley except ValueError: 171eb8dc403SDave Cobbley destdir = '/' 172eb8dc403SDave Cobbley else: 173eb8dc403SDave Cobbley args.target = host 174eb8dc403SDave Cobbley if not destdir.endswith('/'): 175eb8dc403SDave Cobbley destdir += '/' 176eb8dc403SDave Cobbley 177*73bd93f1SPatrick Williams recipe_outdir = srcdir 178eb8dc403SDave Cobbley if not os.path.exists(recipe_outdir) or not os.listdir(recipe_outdir): 179eb8dc403SDave Cobbley raise DevtoolError('No files to deploy - have you built the %s ' 180eb8dc403SDave Cobbley 'recipe? If so, the install step has not installed ' 181eb8dc403SDave Cobbley 'any files.' % args.recipename) 182eb8dc403SDave Cobbley 183eb8dc403SDave Cobbley if args.strip and not args.dry_run: 184eb8dc403SDave Cobbley # Fakeroot copy to new destination 185eb8dc403SDave Cobbley srcdir = recipe_outdir 186*73bd93f1SPatrick Williams recipe_outdir = os.path.join(workdir, 'devtool-deploy-target-stripped') 187eb8dc403SDave Cobbley if os.path.isdir(recipe_outdir): 188*73bd93f1SPatrick Williams exec_fakeroot_no_d(fakerootcmd, fakerootenv, "rm -rf %s" % recipe_outdir, shell=True) 189*73bd93f1SPatrick Williams exec_fakeroot_no_d(fakerootcmd, fakerootenv, "cp -af %s %s" % (os.path.join(srcdir, '.'), recipe_outdir), shell=True) 190*73bd93f1SPatrick Williams os.environ['PATH'] = ':'.join([os.environ['PATH'], path or '']) 191*73bd93f1SPatrick Williams oe.package.strip_execs(args.recipename, recipe_outdir, strip_cmd, libdir, base_libdir, max_process) 192eb8dc403SDave Cobbley 193eb8dc403SDave Cobbley filelist = [] 194c9f7865aSAndrew Geissler inodes = set({}) 195eb8dc403SDave Cobbley ftotalsize = 0 196eb8dc403SDave Cobbley for root, _, files in os.walk(recipe_outdir): 197eb8dc403SDave Cobbley for fn in files: 198c9f7865aSAndrew Geissler fstat = os.lstat(os.path.join(root, fn)) 199eb8dc403SDave Cobbley # Get the size in kiB (since we'll be comparing it to the output of du -k) 200eb8dc403SDave Cobbley # MUST use lstat() here not stat() or getfilesize() since we don't want to 201eb8dc403SDave Cobbley # dereference symlinks 202c9f7865aSAndrew Geissler if fstat.st_ino in inodes: 203c9f7865aSAndrew Geissler fsize = 0 204c9f7865aSAndrew Geissler else: 205c9f7865aSAndrew Geissler fsize = int(math.ceil(float(fstat.st_size)/1024)) 206c9f7865aSAndrew Geissler inodes.add(fstat.st_ino) 207eb8dc403SDave Cobbley ftotalsize += fsize 208eb8dc403SDave Cobbley # The path as it would appear on the target 209eb8dc403SDave Cobbley fpath = os.path.join(destdir, os.path.relpath(root, recipe_outdir), fn) 210eb8dc403SDave Cobbley filelist.append((fpath, fsize)) 211eb8dc403SDave Cobbley 212eb8dc403SDave Cobbley if args.dry_run: 213eb8dc403SDave Cobbley print('Files to be deployed for %s on target %s:' % (args.recipename, args.target)) 214eb8dc403SDave Cobbley for item, _ in filelist: 215eb8dc403SDave Cobbley print(' %s' % item) 216eb8dc403SDave Cobbley return 0 217eb8dc403SDave Cobbley 218eb8dc403SDave Cobbley extraoptions = '' 219eb8dc403SDave Cobbley if args.no_host_check: 220eb8dc403SDave Cobbley extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' 221eb8dc403SDave Cobbley if not args.show_status: 222eb8dc403SDave Cobbley extraoptions += ' -q' 223eb8dc403SDave Cobbley 22419323693SBrad Bishop scp_sshexec = '' 22519323693SBrad Bishop ssh_sshexec = 'ssh' 22619323693SBrad Bishop if args.ssh_exec: 22719323693SBrad Bishop scp_sshexec = "-S %s" % args.ssh_exec 22819323693SBrad Bishop ssh_sshexec = args.ssh_exec 229eb8dc403SDave Cobbley scp_port = '' 230eb8dc403SDave Cobbley ssh_port = '' 231eb8dc403SDave Cobbley if args.port: 232eb8dc403SDave Cobbley scp_port = "-P %s" % args.port 233eb8dc403SDave Cobbley ssh_port = "-p %s" % args.port 234eb8dc403SDave Cobbley 23564c979e8SBrad Bishop if args.key: 23664c979e8SBrad Bishop extraoptions += ' -i %s' % args.key 23764c979e8SBrad Bishop 238eb8dc403SDave Cobbley # In order to delete previously deployed files and have the manifest file on 239eb8dc403SDave Cobbley # the target, we write out a shell script and then copy it to the target 240eb8dc403SDave Cobbley # so we can then run it (piping tar output to it). 241eb8dc403SDave Cobbley # (We cannot use scp here, because it doesn't preserve symlinks.) 242eb8dc403SDave Cobbley tmpdir = tempfile.mkdtemp(prefix='devtool') 243eb8dc403SDave Cobbley try: 244eb8dc403SDave Cobbley tmpscript = '/tmp/devtool_deploy.sh' 245eb8dc403SDave Cobbley tmpfilelist = os.path.join(os.path.dirname(tmpscript), 'devtool_deploy.list') 246eb8dc403SDave Cobbley shellscript = _prepare_remote_script(deploy=True, 247eb8dc403SDave Cobbley verbose=args.show_status, 248eb8dc403SDave Cobbley nopreserve=args.no_preserve, 249eb8dc403SDave Cobbley nocheckspace=args.no_check_space) 250eb8dc403SDave Cobbley # Write out the script to a file 251eb8dc403SDave Cobbley with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f: 252eb8dc403SDave Cobbley f.write(shellscript) 253eb8dc403SDave Cobbley # Write out the file list 254eb8dc403SDave Cobbley with open(os.path.join(tmpdir, os.path.basename(tmpfilelist)), 'w') as f: 255eb8dc403SDave Cobbley f.write('%d\n' % ftotalsize) 256eb8dc403SDave Cobbley for fpath, fsize in filelist: 257eb8dc403SDave Cobbley f.write('%s %d\n' % (fpath, fsize)) 258eb8dc403SDave Cobbley # Copy them to the target 25919323693SBrad Bishop ret = subprocess.call("scp %s %s %s %s/* %s:%s" % (scp_sshexec, scp_port, extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True) 260eb8dc403SDave Cobbley if ret != 0: 261eb8dc403SDave Cobbley raise DevtoolError('Failed to copy script to %s - rerun with -s to ' 262eb8dc403SDave Cobbley 'get a complete error message' % args.target) 263eb8dc403SDave Cobbley finally: 264eb8dc403SDave Cobbley shutil.rmtree(tmpdir) 265eb8dc403SDave Cobbley 266eb8dc403SDave Cobbley # Now run the script 267*73bd93f1SPatrick Williams ret = exec_fakeroot_no_d(fakerootcmd, fakerootenv, 'tar cf - . | %s %s %s %s \'sh %s %s %s %s\'' % (ssh_sshexec, ssh_port, extraoptions, args.target, tmpscript, args.recipename, destdir, tmpfilelist), cwd=recipe_outdir, shell=True) 268eb8dc403SDave Cobbley if ret != 0: 269eb8dc403SDave Cobbley raise DevtoolError('Deploy failed - rerun with -s to get a complete ' 270eb8dc403SDave Cobbley 'error message') 271eb8dc403SDave Cobbley 272eb8dc403SDave Cobbley logger.info('Successfully deployed %s' % recipe_outdir) 273eb8dc403SDave Cobbley 274eb8dc403SDave Cobbley files_list = [] 275eb8dc403SDave Cobbley for root, _, files in os.walk(recipe_outdir): 276eb8dc403SDave Cobbley for filename in files: 277eb8dc403SDave Cobbley filename = os.path.relpath(os.path.join(root, filename), recipe_outdir) 278eb8dc403SDave Cobbley files_list.append(os.path.join(destdir, filename)) 279eb8dc403SDave Cobbley 280eb8dc403SDave Cobbley return 0 281eb8dc403SDave Cobbley 282eb8dc403SDave Cobbleydef undeploy(args, config, basepath, workspace): 283eb8dc403SDave Cobbley """Entry point for the devtool 'undeploy' subcommand""" 284eb8dc403SDave Cobbley if args.all and args.recipename: 285eb8dc403SDave Cobbley raise argparse_oe.ArgumentUsageError('Cannot specify -a/--all with a recipe name', 'undeploy-target') 286eb8dc403SDave Cobbley elif not args.recipename and not args.all: 287eb8dc403SDave Cobbley raise argparse_oe.ArgumentUsageError('If you don\'t specify a recipe, you must specify -a/--all', 'undeploy-target') 288eb8dc403SDave Cobbley 289eb8dc403SDave Cobbley extraoptions = '' 290eb8dc403SDave Cobbley if args.no_host_check: 291eb8dc403SDave Cobbley extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' 292eb8dc403SDave Cobbley if not args.show_status: 293eb8dc403SDave Cobbley extraoptions += ' -q' 294eb8dc403SDave Cobbley 29519323693SBrad Bishop scp_sshexec = '' 29619323693SBrad Bishop ssh_sshexec = 'ssh' 29719323693SBrad Bishop if args.ssh_exec: 29819323693SBrad Bishop scp_sshexec = "-S %s" % args.ssh_exec 29919323693SBrad Bishop ssh_sshexec = args.ssh_exec 300eb8dc403SDave Cobbley scp_port = '' 301eb8dc403SDave Cobbley ssh_port = '' 302eb8dc403SDave Cobbley if args.port: 303eb8dc403SDave Cobbley scp_port = "-P %s" % args.port 304eb8dc403SDave Cobbley ssh_port = "-p %s" % args.port 305eb8dc403SDave Cobbley 306eb8dc403SDave Cobbley args.target = args.target.split(':')[0] 307eb8dc403SDave Cobbley 308eb8dc403SDave Cobbley tmpdir = tempfile.mkdtemp(prefix='devtool') 309eb8dc403SDave Cobbley try: 310eb8dc403SDave Cobbley tmpscript = '/tmp/devtool_undeploy.sh' 311eb8dc403SDave Cobbley shellscript = _prepare_remote_script(deploy=False, dryrun=args.dry_run, undeployall=args.all) 312eb8dc403SDave Cobbley # Write out the script to a file 313eb8dc403SDave Cobbley with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f: 314eb8dc403SDave Cobbley f.write(shellscript) 315eb8dc403SDave Cobbley # Copy it to the target 31619323693SBrad Bishop ret = subprocess.call("scp %s %s %s %s/* %s:%s" % (scp_sshexec, scp_port, extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True) 317eb8dc403SDave Cobbley if ret != 0: 318eb8dc403SDave Cobbley raise DevtoolError('Failed to copy script to %s - rerun with -s to ' 319eb8dc403SDave Cobbley 'get a complete error message' % args.target) 320eb8dc403SDave Cobbley finally: 321eb8dc403SDave Cobbley shutil.rmtree(tmpdir) 322eb8dc403SDave Cobbley 323eb8dc403SDave Cobbley # Now run the script 32419323693SBrad Bishop ret = subprocess.call('%s %s %s %s \'sh %s %s\'' % (ssh_sshexec, ssh_port, extraoptions, args.target, tmpscript, args.recipename), shell=True) 325eb8dc403SDave Cobbley if ret != 0: 326eb8dc403SDave Cobbley raise DevtoolError('Undeploy failed - rerun with -s to get a complete ' 327eb8dc403SDave Cobbley 'error message') 328eb8dc403SDave Cobbley 329eb8dc403SDave Cobbley if not args.all and not args.dry_run: 330eb8dc403SDave Cobbley logger.info('Successfully undeployed %s' % args.recipename) 331eb8dc403SDave Cobbley return 0 332eb8dc403SDave Cobbley 333eb8dc403SDave Cobbley 334eb8dc403SDave Cobbleydef register_commands(subparsers, context): 335eb8dc403SDave Cobbley """Register devtool subcommands from the deploy plugin""" 336eb8dc403SDave Cobbley 337eb8dc403SDave Cobbley parser_deploy = subparsers.add_parser('deploy-target', 338eb8dc403SDave Cobbley help='Deploy recipe output files to live target machine', 339eb8dc403SDave Cobbley description='Deploys a recipe\'s build output (i.e. the output of the do_install task) to a live target machine over ssh. By default, any existing files will be preserved instead of being overwritten and will be restored if you run devtool undeploy-target. Note: this only deploys the recipe itself and not any runtime dependencies, so it is assumed that those have been installed on the target beforehand.', 340eb8dc403SDave Cobbley group='testbuild') 341eb8dc403SDave Cobbley parser_deploy.add_argument('recipename', help='Recipe to deploy') 342eb8dc403SDave Cobbley parser_deploy.add_argument('target', help='Live target machine running an ssh server: user@hostname[:destdir]') 343eb8dc403SDave Cobbley parser_deploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true') 344eb8dc403SDave Cobbley parser_deploy.add_argument('-s', '--show-status', help='Show progress/status output', action='store_true') 345eb8dc403SDave Cobbley parser_deploy.add_argument('-n', '--dry-run', help='List files to be deployed only', action='store_true') 346eb8dc403SDave Cobbley parser_deploy.add_argument('-p', '--no-preserve', help='Do not preserve existing files', action='store_true') 347eb8dc403SDave Cobbley parser_deploy.add_argument('--no-check-space', help='Do not check for available space before deploying', action='store_true') 34819323693SBrad Bishop parser_deploy.add_argument('-e', '--ssh-exec', help='Executable to use in place of ssh') 349eb8dc403SDave Cobbley parser_deploy.add_argument('-P', '--port', help='Specify port to use for connection to the target') 35064c979e8SBrad Bishop parser_deploy.add_argument('-I', '--key', 351d25ed324SAndrew Geissler help='Specify ssh private key for connection to the target') 352eb8dc403SDave Cobbley 353eb8dc403SDave Cobbley strip_opts = parser_deploy.add_mutually_exclusive_group(required=False) 354eb8dc403SDave Cobbley strip_opts.add_argument('-S', '--strip', 355eb8dc403SDave Cobbley help='Strip executables prior to deploying (default: %(default)s). ' 356eb8dc403SDave Cobbley 'The default value of this option can be controlled by setting the strip option in the [Deploy] section to True or False.', 357eb8dc403SDave Cobbley default=oe.types.boolean(context.config.get('Deploy', 'strip', default='0')), 358eb8dc403SDave Cobbley action='store_true') 359eb8dc403SDave Cobbley strip_opts.add_argument('--no-strip', help='Do not strip executables prior to deploy', dest='strip', action='store_false') 360eb8dc403SDave Cobbley 361eb8dc403SDave Cobbley parser_deploy.set_defaults(func=deploy) 362eb8dc403SDave Cobbley 363eb8dc403SDave Cobbley parser_undeploy = subparsers.add_parser('undeploy-target', 364eb8dc403SDave Cobbley help='Undeploy recipe output files in live target machine', 365eb8dc403SDave Cobbley description='Un-deploys recipe output files previously deployed to a live target machine by devtool deploy-target.', 366eb8dc403SDave Cobbley group='testbuild') 367eb8dc403SDave Cobbley parser_undeploy.add_argument('recipename', help='Recipe to undeploy (if not using -a/--all)', nargs='?') 368eb8dc403SDave Cobbley parser_undeploy.add_argument('target', help='Live target machine running an ssh server: user@hostname') 369eb8dc403SDave Cobbley parser_undeploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true') 370eb8dc403SDave Cobbley parser_undeploy.add_argument('-s', '--show-status', help='Show progress/status output', action='store_true') 371eb8dc403SDave Cobbley parser_undeploy.add_argument('-a', '--all', help='Undeploy all recipes deployed on the target', action='store_true') 372eb8dc403SDave Cobbley parser_undeploy.add_argument('-n', '--dry-run', help='List files to be undeployed only', action='store_true') 37319323693SBrad Bishop parser_undeploy.add_argument('-e', '--ssh-exec', help='Executable to use in place of ssh') 374eb8dc403SDave Cobbley parser_undeploy.add_argument('-P', '--port', help='Specify port to use for connection to the target') 37564c979e8SBrad Bishop parser_undeploy.add_argument('-I', '--key', 376d25ed324SAndrew Geissler help='Specify ssh private key for connection to the target') 37764c979e8SBrad Bishop 378eb8dc403SDave Cobbley parser_undeploy.set_defaults(func=undeploy) 379