Coverage for snapcraft/cmds : 45%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- # # Copyright (C) 2015 Canonical Ltd # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 as # published by the Free Software Foundation. # # 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, see <http://www.gnu.org/licenses/>.
version: # the version of the snap # The vendor for the snap (replace 'Vendor <email@example.com>') vendor: Vendor <email@example.com> summary: # 79 char long summary description: # A longer description for the snap icon: # A path to an icon for the package '''
yaml += 'parts:\n' part = lifecycle.load_plugin(part_name, part_name) yaml += ' ' + part.name + ':\n' for opt in part.config.get('options', []): if part.config['options'][opt].get('required', False): yaml += ' ' + opt + ':\n'
config = _load_config() common.env = config.stage_env() userCommand = args.userCommand if not userCommand: userCommand = ['/usr/bin/env', 'PS1=\[\e[1;32m\]snapcraft:\w\$\[\e[0m\] ', '/bin/bash', '--norc'] common.run(userCommand)
cmd(args)
# This check is to support manual assembly. if not os.path.exists(os.path.join(common.get_snapdir(), 'meta')): arches = [snapcraft.common.get_arch(), ]
config = _load_config()
# FIXME this should be done in a more contained manner common.env = config.snap_env()
meta.create(config.data, arches)
# With all the data in snapcraft.yaml, maybe it's not a good idea to call # snap(args) and just do a snappy build if assemble was explicitly called.
stdout=subprocess.PIPE, stderr=subprocess.PIPE,) as proc: else: print('Snapping ...') ret = proc.wait() else:
""" Find the latest private key in ~/.ssh.
:returns: Path of the most-recently-modified private SSH key :raises LookupError: If no such key was found.
This function tries to mimic the logic found in ``ubuntu-device-flash``. It will look for the most recently modified private key in the users' SSH configuration directory. """ candidates = [] ssh_dir = os.path.expanduser('~/.ssh/') for filename in os.listdir(ssh_dir): # Skip public keys, we want the private key if filename.endswith('.pub'): continue ssh_key = os.path.join(ssh_dir, filename) # Skip non-files if not os.path.isfile(ssh_key): continue # Ensure that it is a real ssh key with open(ssh_key, 'rb') as stream: if stream.readline() != b'-----BEGIN RSA PRIVATE KEY-----\n': continue candidates.append(ssh_key) # Sort the keys by modification time, pick the most recent key candidates.sort(key=lambda f: os.stat(f).st_mtime, reverse=True) logger.debug('Available ssh public keys: %r', candidates) if not candidates: raise LookupError('Unable to find any private ssh key') return candidates[0]
# We are mostly making sure we are operating from the correct location. In # the future this could do more by using target attribute in snapcraft.yaml # to create the correct target image. _load_config() # Find the ssh key that ubuntu-device-flash would use so that we can use it # ourselves as well. This may not be the default key that the user has # configured. # See: https://bugs.launchpad.net/snapcraft/+bug/1486659 try: ssh_key = _find_latest_private_key() except LookupError: logger.error('You need to have an SSH key to use this command') logger.error('Please generate one with ssh-keygen(1)') return 1 else: logger.info('Using the following ssh key: %s', ssh_key)
# Find available *.snap files to copy into the test VM snap_dir = os.path.join(os.getcwd()) # copy the snap with the largest version number into the test VM snaps = glob.glob(snap_dir + '/*.snap') snaps.sort() if not snaps: logger.error('There are no .snap files ready') logger.error('Perhaps you forgot to run "snapcraft assemble"') return 1
qemudir = os.path.join(os.getcwd(), 'image') qemu_img = os.path.join(qemudir, '15.04.img') if not os.path.exists(qemu_img): os.makedirs(qemudir, exist_ok=True) logger.info( 'Setting up virtual snappy environment, root access required') common.run([ 'sudo', 'ubuntu-device-flash', 'core', '15.04', '--developer-mode', '--enable-ssh', '-o', os.path.relpath(qemu_img, qemudir)], cwd=qemudir) qemu = None try: # Allow the developer to provide additional arguments to qemu. This # can be used, for example, to pass through USB devices from the host. # This can enable a lot of hardware-specific use cases directly inside # the snapcraft run workflow. # # For example: # $ export SNAPCRAFT_RUN_QEMU_ARGS=\ # "-usb -device usb-host,hostbus=1,hostaddr=10" # $ snapcraft run qemu_args = os.getenv('SNAPCRAFT_RUN_QEMU_ARGS') if qemu_args is not None: qemu_args = shlex.split(qemu_args) else: qemu_args = [] qemu = subprocess.Popen( ['kvm', '-m', '768', '-nographic', '-snapshot', '-redir', 'tcp:8022::22', qemu_img] + qemu_args, stdin=subprocess.PIPE) n = tempfile.NamedTemporaryFile() ssh_opts = [ # We want to login with the specified ssh identity (key) '-i', ssh_key, # We don't want strict host checking because it's a new VM with a # random key each time. '-oStrictHostKeyChecking=no', # We don't want to pollute the known_hosts file with new entries # all the time so let's use a temporary file for that '-oUserKnownHostsFile={}'.format(n.name), # Don't try keyboard interactive authentication, we're expecting to # login via the key and if that doesn't work then everything else # will fail anyway. '-oKbdInteractiveAuthentication=no', ] while True: ret_code = _call( ['ssh'] + ssh_opts + ['ubuntu@localhost', '-p', '8022', 'true']) if ret_code == 0: break print('Waiting for device') time.sleep(1) # copy the most recent snap into the test VM _check_call( ['scp'] + ssh_opts + [ '-P', '8022', snaps[-1], 'ubuntu@localhost:~/']) # install the snap _check_call( ['ssh'] + ssh_opts + ['ubuntu@localhost', '-p', '8022', 'sudo snappy install *.snap']) # "login" _call( ['ssh'] + ssh_opts + ['-p', '8022', 'ubuntu@localhost'], preexec_fn=os.setsid) finally: if qemu: qemu.kill()
snapcraft.plugins.__path__):
'\'snapcraft.yaml\''.format(part_name))
# parts dir does not contain only generated code. not os.listdir(common.get_partsdir())):
# Gather our own files up
# Scan previous parts for collisions parts_files[other_part_name]['installdir'], f) continue
'paths in common which have different ' 'contents:\n %s', other_part_name, part.name, '\n '.join(sorted(conflict_files)))
# And add our files to the list 'installdir': part.installdir}
forceAll = args.force forceCommand = None
cmds = [args.cmd]
if cmds[0] in common.COMMAND_ORDER: forceCommand = cmds[0] cmds = common.COMMAND_ORDER[0:common.COMMAND_ORDER.index(cmds[0]) + 1]
config = _load_config() _install_build_packages(config.build_tools)
# clean the snap dir before Snapping snap_clean = False
for part in config.all_parts: for cmd in cmds: if cmd is 'stage': # This ends up running multiple times, as each part gets to its # staging cmd. That's inefficient, but largely OK. # FIXME: fix the above by iterating over cmds before iterating # all_parts. But then we need to make sure we continue to # handle cases like go, where you want go built before trying # to pull a go project. if not _check_for_collisions(config.all_parts): sys.exit(1)
# We want to make sure we have a clean snap dir if cmd is 'snap' and not snap_clean: shutil.rmtree(common.get_snapdir()) snap_clean = True
common.env = config.build_env_for_part(part) force = forceAll or cmd == forceCommand
try: getattr(part, cmd)(force=force) except Exception as e: logger.error('Failed doing %s for %s: %s', cmd, part.name, e) sys.exit(1)
logger.info('Running: %s', ' '.join(shlex.quote(arg) for arg in args)) return subprocess.call(args, **kwargs)
logger.info('Running: %s', ' '.join(shlex.quote(arg) for arg in args)) return subprocess.check_call(args, **kwargs)
new_packages = [] for pkg in packages: try: if not apt.Cache()[pkg].installed: new_packages.append(pkg) except KeyError: logger.error('Could not find all the "build-packages" required ' 'in snapcraft.yaml') sys.exit(1) if new_packages: logger.info('Installing required packages on the host system') _check_call(['sudo', 'apt-get', '-o', 'Dpkg::Progress-Fancy=1', '--no-install-recommends', '-y', 'install'] + new_packages)
global _config return _config
return _config logger.error( 'Could not find {}. Are you sure you are in the right ' 'directory?\nTo start a new project, use \'snapcraft ' 'init\''.format(e.file)) sys.exit(1) msg = 'Issues while validating snapcraft.yaml: {}'.format(e.message) logger.error(msg) sys.exit(1) logger.error( 'Issues while validating snapcraft.yaml: the "plugin" keyword is ' 'missing for the "{}" part.'.format(e.part)) sys.exit(1) logger.error('Issue detected while analyzing ' 'snapcraft.yaml: {}'.format(e.message)) sys.exit(1) |