Exemplo n.º 1
0
    def test_strip_defaults(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml()

        strip.main()

        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'package.yaml')),
            'Expected a package.yaml')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[0]['part_dir']),
                        'Expected a part directory for the build0 part')
        self.assertTrue(os.path.exists(parts[0]['state_file']),
                        'Expected a state file for the build0 part')

        with open(parts[0]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(
            len(state), 1, 'Expected only one line in the state '
            'file for the build0 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "build0 to be 'strip'")
Exemplo n.º 2
0
def _cleanup_common_directories(config):
    _remove_directory_if_empty(common.get_partsdir())
    _remove_directory_if_empty(common.get_stagedir())
    _remove_directory_if_empty(common.get_snapdir())

    max_index = -1
    for part in config.all_parts:
        step = part.last_step()
        if step:
            index = common.COMMAND_ORDER.index(step)
            if index > max_index:
                max_index = index

    # If no parts have been pulled, remove the parts directory. In most cases
    # this directory should have already been cleaned, but this handles the
    # case of a failed pull.
    should_remove_partsdir = max_index < common.COMMAND_ORDER.index('pull')
    if should_remove_partsdir and os.path.exists(common.get_partsdir()):
        logger.info('Cleaning up parts directory')
        shutil.rmtree(common.get_partsdir())

    # If no parts have been staged, remove staging area.
    should_remove_stagedir = max_index < common.COMMAND_ORDER.index('stage')
    if should_remove_stagedir and os.path.exists(common.get_stagedir()):
        logger.info('Cleaning up staging area')
        shutil.rmtree(common.get_stagedir())

    # If no parts have been stripped, remove snapping area.
    should_remove_snapdir = max_index < common.COMMAND_ORDER.index('strip')
    if should_remove_snapdir and os.path.exists(common.get_snapdir()):
        logger.info('Cleaning up snapping area')
        shutil.rmtree(common.get_snapdir())
Exemplo n.º 3
0
def main(argv=None):
    argv = argv if argv else []
    args = docopt(__doc__, argv=argv)

    config = snapcraft.yaml.load_config()

    if args['PART']:
        config.validate_parts(args['PART'])

    for part in config.all_parts:
        if not args['PART'] or part.name in args['PART']:
            part.clean()

    # parts dir does not contain only generated code.
    if (os.path.exists(common.get_partsdir()) and
            not os.listdir(common.get_partsdir())):
        os.rmdir(common.get_partsdir())

    parts_match = set(config.part_names) == set(args['PART'])
    # Only clean stage if all the parts were cleaned up.
    clean_stage = not args['PART'] or parts_match
    if clean_stage and os.path.exists(common.get_stagedir()):
        logger.info('Cleaning up staging area')
        shutil.rmtree(common.get_stagedir())

    if os.path.exists(common.get_snapdir()):
        logger.info('Cleaning up snapping area')
        shutil.rmtree(common.get_snapdir())
Exemplo n.º 4
0
    def test_strip_defaults(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml()

        strip.main()

        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'snap.yaml')),
            'Expected a snap.yaml')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[0]['part_dir']),
                        'Expected a part directory for the build0 part')
        self.assertTrue(os.path.exists(parts[0]['state_file']),
                        'Expected a state file for the build0 part')

        with open(parts[0]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(len(state), 1, 'Expected only one line in the state '
                         'file for the build0 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "build0 to be 'strip'")
Exemplo n.º 5
0
    def test_clean_strip_after_fileset_change(self):
        # Create part1 and get it through the "build" step.
        handler = pluginhandler.load_plugin('part1', 'nil')
        handler.makedirs()

        bindir = os.path.join(handler.code.installdir, 'bin')
        os.makedirs(bindir)
        open(os.path.join(bindir, '1'), 'w').close()
        open(os.path.join(bindir, '2'), 'w').close()

        handler.mark_done('build')
        handler.stage()
        handler.strip()

        # Verify that both files have been stripped
        self.assertTrue(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '1')))
        self.assertTrue(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '2')))

        # Now update the `snap` fileset to only snap one of these files
        handler.code.options.snap = ['bin/1']

        # Now clean the strip step for part1
        handler.clean_strip({})

        # Verify that part1's file is no longer stripped
        self.assertFalse(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '1')),
            'Expected bin/1 to be cleaned')
        self.assertFalse(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '2')),
            'Expected bin/2 to be cleaned as well, even though the filesets '
            'changed since it was stripped.')
Exemplo n.º 6
0
    def test_strip_one_part_only_from_3(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml(n=3)

        strip.main(['strip1', ])

        self.assertFalse(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'snap.yaml')),
            'There should not be a snap.yaml')
        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the strip1 part')
        self.assertTrue(os.path.exists(parts[1]['state_file']),
                        'Expected a state file for the strip1 part')

        with open(parts[1]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(len(state), 1, 'Expected only one line in the state '
                         'file for the strip1 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         " strip1 to be 'strip'")

        for i in [0, 2]:
            self.assertFalse(os.path.exists(parts[i]['part_dir']),
                             'Pulled wrong part')
            self.assertFalse(os.path.exists(parts[i]['state_file']),
                             'Expected for only to be a state file for build1')
Exemplo n.º 7
0
    def test_clean_all(self):
        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call('partdir1'),
            mock.call().__bool__(),
            mock.call('partdir2'),
            mock.call().__bool__(),
            mock.call('partdir3'),
            mock.call().__bool__(),
            mock.call(common.get_partsdir()),
            mock.call().__bool__(),
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call('partdir1'),
            mock.call('partdir2'),
            mock.call('partdir3'),
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
Exemplo n.º 8
0
def clean(args):
    config = _load_config()

    part_names = {part.name for part in config.all_parts}
    for part_name in args.parts:
        if part_name not in part_names:
            logger.error('The part named {!r} is not defined in '
                         '\'snapcraft.yaml\''.format(part_name))
            sys.exit(1)

    for part in config.all_parts:
        if not args.parts or part.name in args.parts:
            part.clean()

    # parts dir does not contain only generated code.
    if (os.path.exists(common.get_partsdir()) and
            not os.listdir(common.get_partsdir())):
        os.rmdir(common.get_partsdir())

    clean_stage = not args.parts or part_names == set(args.parts)
    if clean_stage and os.path.exists(common.get_stagedir()):
        logger.info('Cleaning up staging area')
        shutil.rmtree(common.get_stagedir())

    if os.path.exists(common.get_snapdir()):
        logger.info('Cleaning up snapping area')
        shutil.rmtree(common.get_snapdir())
Exemplo n.º 9
0
    def test_clean_all(self):
        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call('partdir1'),
            mock.call().__bool__(),
            mock.call('partdir2'),
            mock.call().__bool__(),
            mock.call('partdir3'),
            mock.call().__bool__(),
            mock.call(common.get_partsdir()),
            mock.call().__bool__(),
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call('partdir1'),
            mock.call('partdir2'),
            mock.call('partdir3'),
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
Exemplo n.º 10
0
    def test_strip_one_part_only_from_3(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml(n=3)

        main(['strip', 'strip1'])

        self.assertFalse(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'snap.yaml')),
            'There should not be a snap.yaml')
        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the strip1 part')

        self.verify_state('strip1', parts[1]['state_dir'], 'strip')

        for i in [0, 2]:
            self.assertFalse(os.path.exists(parts[i]['part_dir']),
                             'Pulled wrong part')
            self.assertFalse(os.path.exists(parts[i]['state_dir']),
                             'Expected for only to be a state file for build1')
Exemplo n.º 11
0
    def test_partial_clean(self):
        parts = self.make_snapcraft_yaml(n=3)

        clean.main(['clean0', 'clean2'])

        for i in [0, 2]:
            self.assertFalse(
                os.path.exists(parts[i]['part_dir']),
                'Expected for {!r} to be wiped'.format(parts[i]['part_dir']))

        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the clean1 part')

        self.assertTrue(os.path.exists(common.get_partsdir()))
        self.assertTrue(os.path.exists(common.get_stagedir()))
        self.assertTrue(os.path.exists(common.get_snapdir()))

        # Now clean it the rest of the way
        clean.main(['clean1'])

        for i in range(0, 3):
            self.assertFalse(
                os.path.exists(parts[i]['part_dir']),
                'Expected for {!r} to be wiped'.format(parts[i]['part_dir']))

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemplo n.º 12
0
    def test_partial_clean(self):
        parts = self.make_snapcraft_yaml(n=3)

        main(["clean", "clean0", "clean2"])

        for i in [0, 2]:
            self.assertFalse(
                os.path.exists(parts[i]["part_dir"]), "Expected for {!r} to be wiped".format(parts[i]["part_dir"])
            )

        self.assertTrue(os.path.exists(parts[1]["part_dir"]), "Expected a part directory for the clean1 part")

        self.assertTrue(os.path.exists(common.get_partsdir()))
        self.assertTrue(os.path.exists(common.get_stagedir()))
        self.assertTrue(os.path.exists(common.get_snapdir()))

        # Now clean it the rest of the way
        main(["clean", "clean1"])

        for i in range(0, 3):
            self.assertFalse(
                os.path.exists(parts[i]["part_dir"]), "Expected for {!r} to be wiped".format(parts[i]["part_dir"])
            )

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemplo n.º 13
0
    def clear_common_directories(self):
        if os.path.exists(common.get_partsdir()):
            shutil.rmtree(common.get_partsdir())

        if os.path.exists(common.get_stagedir()):
            shutil.rmtree(common.get_stagedir())

        if os.path.exists(common.get_snapdir()):
            shutil.rmtree(common.get_snapdir())
Exemplo n.º 14
0
    def test_clean_strip(self):
        filesets = {
            'all': {
                'fileset': ['*'],
            },
            'no1': {
                'fileset': ['-1'],
            },
            'onlya': {
                'fileset': ['a'],
            },
            'onlybase': {
                'fileset': ['*', '-*/*'],
            },
            'nostara': {
                'fileset': ['-*/a'],
            },
        }

        for key, value in filesets.items():
            with self.subTest(key=key):
                self.clear_common_directories()

                handler = pluginhandler.load_plugin('test_part', 'nil', {
                    'snap': value['fileset']
                })
                handler.makedirs()

                installdir = handler.code.installdir
                os.makedirs(installdir + '/1/1a/1b')
                os.makedirs(installdir + '/2/2a')
                os.makedirs(installdir + '/3')
                open(installdir + '/a', mode='w').close()
                open(installdir + '/b', mode='w').close()
                open(installdir + '/1/a', mode='w').close()
                open(installdir + '/3/a', mode='w').close()

                handler.mark_done('build')

                # Stage the installed files
                handler.stage()

                # Now strip them
                handler.strip()

                self.assertTrue(os.listdir(common.get_snapdir()))

                handler.clean_strip({})

                self.assertFalse(os.listdir(common.get_snapdir()),
                                 'Expected snapdir to be completely cleaned')
Exemplo n.º 15
0
    def test_clean_nested_dependent_parts(self):
        yaml = """name: clean-test
version: 1.0
summary: test clean
description: test clean

parts:
  main:
    plugin: nil
    source: .

  dependent:
    plugin: nil
    source: .
    after: [main]

  dependent-dependent:
    plugin: nil
    source: .
    after: [dependent]"""

        super().make_snapcraft_yaml(yaml)

        part_dirs = {}
        for part in ['main', 'dependent', 'dependent-dependent']:
            part_dirs[part] = os.path.join(common.get_partsdir(), part)
            os.makedirs(part_dirs[part])

        os.makedirs(common.get_stagedir())
        os.makedirs(common.get_snapdir())

        # Cleaning only `main`. Since `dependent` depends upon main, we expect
        # that it will be cleaned as well. Otherwise it won't be using the new
        # `main` when it is built.
        clean.main(['main'])

        self.assertFalse(os.path.exists(part_dirs['main']),
                         'Expected part directory for main to be cleaned')
        self.assertFalse(
            os.path.exists(part_dirs['dependent']),
            'Expected part directory for dependent to be cleaned as it '
            'depends upon main')

        self.assertFalse(
            os.path.exists(part_dirs['dependent-dependent']),
            'Expected part directory for dependent-dependent to be cleaned as '
            'it depends upon dependent, which depends upon main')

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemplo n.º 16
0
    def test_cleanbuild(self, mock_installed, mock_call):
        mock_installed.return_value = True

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml()
        # simulate build artifacts

        dirs = [
            os.path.join(common.get_partsdir(), 'part1', 'src'),
            common.get_stagedir(),
            common.get_snapdir(),
            os.path.join(common.get_partsdir(), 'plugins'),
        ]
        files_tar = [
            os.path.join(common.get_partsdir(), 'plugins', 'x-plugin.py'),
            'main.c',
        ]
        files_no_tar = [
            os.path.join(common.get_stagedir(), 'binary'),
            os.path.join(common.get_snapdir(), 'binary'),
            'snap-test.snap',
            'snap-test_1.0_source.tar.bz2',
        ]
        for d in dirs:
            os.makedirs(d)
        for f in files_tar + files_no_tar:
            open(f, 'w').close()

        cleanbuild.main()

        self.assertEqual(
            'Setting up container with project assets\n'
            'Waiting for a network connection...\n'
            'Network connection established\n'
            'Retrieved snap-test_1.0_amd64.snap\n',
            fake_logger.output)

        with tarfile.open('snap-test_1.0_source.tar.bz2') as tar:
            tar_members = tar.getnames()

        for f in files_no_tar:
            f = os.path.relpath(f)
            self.assertFalse('./{}'.format(f) in tar_members,
                             '{} should not be in {}'.format(f, tar_members))
        for f in files_tar:
            f = os.path.relpath(f)
            self.assertTrue('./{}'.format(f) in tar_members,
                            '{} should be in {}'.format(f, tar_members))
Exemplo n.º 17
0
    def test_cleanbuild(self, mock_installed, mock_call):
        mock_installed.return_value = True

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml()
        # simulate build artifacts

        dirs = [
            os.path.join(common.get_partsdir(), 'part1', 'src'),
            common.get_stagedir(),
            common.get_snapdir(),
            os.path.join(common.get_partsdir(), 'plugins'),
        ]
        files_tar = [
            os.path.join(common.get_partsdir(), 'plugins', 'x-plugin.py'),
            'main.c',
        ]
        files_no_tar = [
            os.path.join(common.get_stagedir(), 'binary'),
            os.path.join(common.get_snapdir(), 'binary'),
            'snap-test.snap',
            'snap-test_1.0_source.tar.bz2',
        ]
        for d in dirs:
            os.makedirs(d)
        for f in files_tar + files_no_tar:
            open(f, 'w').close()

        cleanbuild.main()

        self.assertEqual(
            'Setting up container with project assets\n'
            'Waiting for a network connection...\n'
            'Network connection established\n'
            'Retrieved snap-test_1.0_amd64.snap\n', fake_logger.output)

        with tarfile.open('snap-test_1.0_source.tar.bz2') as tar:
            tar_members = tar.getnames()

        for f in files_no_tar:
            f = os.path.relpath(f)
            self.assertFalse('./{}'.format(f) in tar_members,
                             '{} should not be in {}'.format(f, tar_members))
        for f in files_tar:
            f = os.path.relpath(f)
            self.assertTrue('./{}'.format(f) in tar_members,
                            '{} should be in {}'.format(f, tar_members))
Exemplo n.º 18
0
    def test_clean_strip_multiple_independent_parts(self):
        # Create part1 and get it through the "build" step.
        handler1 = pluginhandler.load_plugin('part1', 'nil')
        handler1.makedirs()

        bindir = os.path.join(handler1.code.installdir, 'bin')
        os.makedirs(bindir)
        open(os.path.join(bindir, '1'), 'w').close()

        handler1.mark_done('build')

        # Now create part2 and get it through the "build" step.
        handler2 = pluginhandler.load_plugin('part2', 'nil')
        handler2.makedirs()

        bindir = os.path.join(handler2.code.installdir, 'bin')
        os.makedirs(bindir)
        open(os.path.join(bindir, '2'), 'w').close()

        handler2.mark_done('build')

        # Now stage both parts
        handler1.stage()
        handler2.stage()

        # And strip both parts
        handler1.strip()
        handler2.strip()

        # Verify that part1's file has been stripped
        self.assertTrue(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '1')))

        # Verify that part2's file has been stripped
        self.assertTrue(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '2')))

        # Now clean the strip step for part1
        handler1.clean_strip({})

        # Verify that part1's file is no longer stripped
        self.assertFalse(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '1')),
            "Expected part1's stripped files to be cleaned")

        # Verify that part2's file is still there
        self.assertTrue(
            os.path.exists(os.path.join(common.get_snapdir(), 'bin', '2')),
            "Expected part2's stripped files to be untouched")
Exemplo n.º 19
0
def _wrap_exe(relexepath):
    snap_dir = common.get_snapdir()
    exepath = os.path.join(snap_dir, relexepath)
    wrappath = exepath + '.wrapper'

    # TODO talk to original author if the exception to be captured here is
    # FileNotFoundError, the original code was a general catch all
    try:
        os.remove(wrappath)
    except FileNotFoundError:
        pass

    wrapexec = '$SNAP_APP_PATH/{}'.format(relexepath)
    if not os.path.exists(exepath) and '/' not in relexepath:
        # If it doesn't exist it might be in the path
        logger.debug('Checking to see if "{}" is in the $PATH'.format(
            relexepath))
        with tempfile.NamedTemporaryFile('w+') as tempf:
            script = ('#!/bin/sh\n' +
                      '{}\n'.format(common.assemble_env()) +
                      'which "{}"\n'.format(relexepath))
            tempf.write(script)
            tempf.flush()
            common.run(['/bin/sh', tempf.name], cwd=snap_dir)
            wrapexec = relexepath

    _write_wrap_exe(wrapexec, wrappath)

    return os.path.relpath(wrappath, snap_dir)
Exemplo n.º 20
0
def create(config_data, arches=None):
    '''
    Create  the meta directory and provision it with package.yaml and readme.md
    in the snap dir using information from config_data and arches.
    If provided arches, is a list of arches.

    Returns meta_dir.
    '''
    # TODO keys for using apparmor, setting an icon missing.

    meta_dir = os.path.join(common.get_snapdir(), 'meta')
    os.makedirs(meta_dir, exist_ok=True)

    config_data['icon'] = _copy(meta_dir, config_data['icon'])

    if 'framework-policy' in config_data:
        _copy(meta_dir, config_data['framework-policy'], 'framework-policy')

    _write_package_yaml(meta_dir, config_data, arches)
    _write_readme_md(meta_dir, config_data)

    if 'config' in config_data:
        _setup_config_hook(meta_dir, config_data['config'])

    return meta_dir
Exemplo n.º 21
0
def _wrap_exe(relexepath):
    snap_dir = common.get_snapdir()
    exepath = os.path.join(snap_dir, relexepath)
    wrappath = exepath + '.wrapper'

    # TODO talk to original author if the exception to be captured here is
    # FileNotFoundError, the original code was a general catch all
    try:
        os.remove(wrappath)
    except FileNotFoundError:
        pass

    wrapexec = '$SNAP_APP_PATH/{}'.format(relexepath)
    if not os.path.exists(exepath) and '/' not in relexepath:
        # If it doesn't exist it might be in the path
        logger.debug(
            'Checking to see if "{}" is in the $PATH'.format(relexepath))
        with tempfile.NamedTemporaryFile('w+') as tempf:
            script = ('#!/bin/sh\n' + '{}\n'.format(common.assemble_env()) +
                      'which "{}"\n'.format(relexepath))
            tempf.write(script)
            tempf.flush()
            common.run(['/bin/sh', tempf.name], cwd=snap_dir)
            wrapexec = relexepath

    _write_wrap_exe(wrapexec, wrappath)

    return os.path.relpath(wrappath, snap_dir)
Exemplo n.º 22
0
def create(config_data, arches=None):
    '''
    Create  the meta directory and provision it with package.yaml and readme.md
    in the snap dir using information from config_data and arches.
    If provided arches, is a list of arches.

    Returns meta_dir.
    '''
    # TODO keys for using apparmor, setting an icon missing.

    meta_dir = os.path.join(common.get_snapdir(), 'meta')
    os.makedirs(meta_dir, exist_ok=True)

    config_data['icon'] = _copy(meta_dir, config_data['icon'])

    if 'framework-policy' in config_data:
        _copy(meta_dir, config_data['framework-policy'], 'framework-policy')

    _write_package_yaml(meta_dir, config_data, arches)
    _write_readme_md(meta_dir, config_data)

    if 'config' in config_data:
        _setup_config_hook(meta_dir, config_data['config'])

    return meta_dir
Exemplo n.º 23
0
    def test_non_shebang_binaries_ignored(self):
        """Native binaries are ignored.

        If the executable is a native binary, and thus not have a
        shebang, it's ignored.
        """
        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        # Choose a content which can't be decoded with utf-8, to make
        # sure no decoding errors happen.
        exe_contents = b'\xf0\xf1'
        with open(os.path.join(snapdir, relative_exe_path), 'wb') as exe:
            exe.write(exe_contents)

        relative_wrapper_path = meta._wrap_exe(relative_exe_path)
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        expected = ('#!/bin/sh\n'
                    '\n\n'
                    'exec "$SNAP/test_relexepath" $*\n')
        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
        with open(os.path.join(snapdir, relative_exe_path), 'rb') as exe:
            self.assertEqual(exe_contents, exe.read())
Exemplo n.º 24
0
def assemble(args):
    args.cmd = 'snap'
    # 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.
    snap(args)

    ticker = '/-\\|'
    i = 0
    with subprocess.Popen(['snappy', 'build', common.get_snapdir()],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,) as proc:
        ret = None
        if os.isatty(sys.stdout.fileno()):
            ret = proc.poll()
            while ret is None:
                print('\033[1m\rSnapping\033[0m {}'.format(ticker[i]), end='')
                i = (i+1) % len(ticker)
                time.sleep(.2)
                ret = proc.poll()
        else:
            print('Snapping ...')
            ret = proc.wait()
        print()
        if ret == 0:
            print(proc.stdout.read().decode('utf-8'))
        else:
            print(proc.stderr.read().decode('utf-8'), file=sys.stderr)
        sys.exit(ret)
Exemplo n.º 25
0
def _write_wrap_exe(wrapexec, wrappath, shebang=None, args=None, cwd=None):
    args = ' '.join(args) + ' $*' if args else '$*'
    cwd = 'cd {}'.format(cwd) if cwd else ''

    snap_dir = common.get_snapdir()
    assembled_env = common.assemble_env().replace(snap_dir, '$SNAP')
    replace_path = r'{}/[a-z0-9][a-z0-9+-]*/install'.format(
        common.get_partsdir())
    assembled_env = re.sub(replace_path, '$SNAP', assembled_env)
    executable = '"{}"'.format(wrapexec)
    if shebang is not None:
        new_shebang = re.sub(replace_path, '$SNAP', shebang)
        if new_shebang != shebang:
            # If the shebang was pointing to and executable within the
            # local 'parts' dir, have the wrapper script execute it
            # directly, since we can't use $SNAP in the shebang itself.
            executable = '"{}" "{}"'.format(new_shebang, wrapexec)
    script = ('#!/bin/sh\n' +
              '{}\n'.format(assembled_env) +
              '{}\n'.format(cwd) +
              'exec {} {}\n'.format(executable, args))

    with open(wrappath, 'w+') as f:
        f.write(script)

    os.chmod(wrappath, 0o755)
Exemplo n.º 26
0
    def test_wrap_exe_must_write_wrapper(self, mock_assemble_env):
        mock_assemble_env.return_value = """\
PATH={0}/part1/install/usr/bin:{0}/part1/install/bin
""".format(common.get_partsdir())

        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        open(os.path.join(snapdir, relative_exe_path), 'w').close()

        # Check that the wrapper is created even if there is already a file
        # with the same name.
        open(os.path.join('snap', 'test_relexepath.wrapper'), 'w').close()

        relative_wrapper_path = meta._wrap_exe(relative_exe_path)
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        expected = ('#!/bin/sh\n'
                    'PATH=$SNAP/usr/bin:$SNAP/bin\n'
                    '\n\n'
                    'exec "$SNAP/test_relexepath" $*\n')

        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
Exemplo n.º 27
0
    def test_non_shebang_binaries_ignored(self):
        """Native binaries are ignored.

        If the executable is a native binary, and thus not have a
        shebang, it's ignored.
        """
        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        # Choose a content which can't be decoded with utf-8, to make
        # sure no decoding errors happen.
        exe_contents = b'\xf0\xf1'
        with open(os.path.join(snapdir, relative_exe_path), 'wb') as exe:
            exe.write(exe_contents)

        relative_wrapper_path = meta._wrap_exe(relative_exe_path)
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        expected = ('#!/bin/sh\n' '\n\n' 'exec "$SNAP/test_relexepath" $*\n')
        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
        with open(os.path.join(snapdir, relative_exe_path), 'rb') as exe:
            self.assertEqual(exe_contents, exe.read())
Exemplo n.º 28
0
def _wrap_exe(relexepath, args=None):
    snap_dir = common.get_snapdir()
    exepath = os.path.join(snap_dir, relexepath)
    wrappath = exepath + ".wrapper"
    shebang = None

    # TODO talk to original author if the exception to be captured here is
    # FileNotFoundError, the original code was a general catch all
    try:
        os.remove(wrappath)
    except FileNotFoundError:
        pass

    wrapexec = "$SNAP_APP_PATH/{}".format(relexepath)
    if not os.path.exists(exepath) and "/" not in relexepath:
        # If it doesn't exist it might be in the path
        logger.debug('Checking to see if "{}" is in the $PATH'.format(relexepath))
        with tempfile.NamedTemporaryFile("w+") as tempf:
            script = "#!/bin/sh\n" + "{}\n".format(common.assemble_env()) + 'which "{}"\n'.format(relexepath)
            tempf.write(script)
            tempf.flush()
            common.run(["/bin/sh", tempf.name], cwd=snap_dir)
            wrapexec = relexepath
    else:
        with open(exepath, "rb") as exefile:
            # If the file has a she-bang, the path might be pointing to
            # the local 'parts' dir. Extract it so that _write_wrap_exe
            # will have a chance to rewrite it.
            if exefile.read(2) == b"#!":
                shebang = exefile.readline().strip().decode("utf-8")

    _write_wrap_exe(wrapexec, wrappath, shebang=shebang, args=args)

    return os.path.relpath(wrappath, snap_dir)
Exemplo n.º 29
0
def _wrap_exe(command, basename=None):
    execparts = shlex.split(command)
    snap_dir = common.get_snapdir()
    exepath = os.path.join(snap_dir, execparts[0])
    if basename:
        wrappath = os.path.join(snap_dir, basename) + '.wrapper'
    else:
        wrappath = exepath + '.wrapper'
    shebang = None

    if os.path.exists(wrappath):
        os.remove(wrappath)

    wrapexec = '$SNAP/{}'.format(execparts[0])
    if not os.path.exists(exepath) and '/' not in execparts[0]:
        _find_bin(execparts[0], snap_dir)
        wrapexec = execparts[0]
    else:
        with open(exepath, 'rb') as exefile:
            # If the file has a she-bang, the path might be pointing to
            # the local 'parts' dir. Extract it so that _write_wrap_exe
            # will have a chance to rewrite it.
            if exefile.read(2) == b'#!':
                shebang = exefile.readline().strip().decode('utf-8')

    _write_wrap_exe(wrapexec, wrappath, shebang=shebang, args=execparts[1:])

    return os.path.relpath(wrappath, snap_dir)
Exemplo n.º 30
0
    def test_wrap_exe_writes_wrapper_with_basename(self, mock_assemble_env):
        mock_assemble_env.return_value = """\
PATH={0}/part1/install/usr/bin:{0}/part1/install/bin
""".format(common.get_partsdir())

        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        open(os.path.join(snapdir, relative_exe_path), 'w').close()

        relative_wrapper_path = meta._wrap_exe(
            relative_exe_path, basename='new-name')
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        self.assertEqual(relative_wrapper_path, 'new-name.wrapper')

        expected = ('#!/bin/sh\n'
                    'PATH=$SNAP/usr/bin:$SNAP/bin\n'
                    '\n\n'
                    'exec "$SNAP/test_relexepath" $*\n')
        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
Exemplo n.º 31
0
def create(config_data, arches=None):
    """
    Create  the meta directory and provision it with package.yaml and readme.md
    in the snap dir using information from config_data and arches.
    If provided arches, is a list of arches.

    Returns meta_dir.
    """
    # TODO keys for using apparmor, setting an icon missing.

    meta_dir = os.path.join(common.get_snapdir(), "meta")
    os.makedirs(meta_dir, exist_ok=True)

    config_data["icon"] = _copy(meta_dir, config_data["icon"])

    if "framework-policy" in config_data:
        _copy(meta_dir, config_data["framework-policy"], "framework-policy")

    _write_package_yaml(meta_dir, config_data, arches)
    _write_readme_md(meta_dir, config_data)

    if "config" in config_data:
        _setup_config_hook(meta_dir, config_data["config"])

    return meta_dir
Exemplo n.º 32
0
    def test_snap_defaults(self, mock_call):
        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)
        self.make_snapcraft_yaml()

        snap.main()

        self.assertEqual(
            'Pulling part1 \n'
            'Building part1 \n'
            'Staging part1 \n'
            'Stripping part1 \n'
            'Snapping snap-test_1.0_amd64.snap\n'
            'Snapped snap-test_1.0_amd64.snap\n',
            fake_logger.output)

        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(self.state_file,
                        'Expected a state file for the part1 part')

        with open(self.state_file) as sf:
            state = sf.readlines()
        self.assertEqual(len(state), 1, 'Expected only one line in the state '
                         'file for the part1 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "part1 to be 'strip'")

        mock_call.assert_called_once_with([
            'mksquashfs', common.get_snapdir(), 'snap-test_1.0_amd64.snap',
            '-noappend', '-comp', 'xz'])
Exemplo n.º 33
0
def _wrap_exe(command, basename=None):
    execparts = shlex.split(command)
    snap_dir = common.get_snapdir()
    exepath = os.path.join(snap_dir, execparts[0])
    if basename:
        wrappath = os.path.join(snap_dir, basename) + '.wrapper'
    else:
        wrappath = exepath + '.wrapper'
    shebang = None

    if os.path.exists(wrappath):
        os.remove(wrappath)

    wrapexec = '$SNAP/{}'.format(execparts[0])
    if not os.path.exists(exepath) and '/' not in execparts[0]:
        _find_bin(execparts[0], snap_dir)
        wrapexec = execparts[0]
    else:
        with open(exepath, 'rb') as exefile:
            # If the file has a she-bang, the path might be pointing to
            # the local 'parts' dir. Extract it so that _write_wrap_exe
            # will have a chance to rewrite it.
            if exefile.read(2) == b'#!':
                shebang = exefile.readline().strip().decode('utf-8')

    _write_wrap_exe(wrapexec, wrappath, shebang=shebang, args=execparts[1:])

    return os.path.relpath(wrappath, snap_dir)
Exemplo n.º 34
0
    def test_non_snap_shebangs_ignored(self):
        """Shebangs not pointing to the snap's install dir are ignored.

        If the shebang points to a system executable, there's no need to
        interfere.
        """
        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        exe_contents = '#!/bin/bash\necho hello\n'
        with open(os.path.join(snapdir, relative_exe_path), 'w') as exe:
            exe.write(exe_contents)

        relative_wrapper_path = meta._wrap_exe(relative_exe_path)
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        expected = ('#!/bin/sh\n'
                    '\n\n'
                    'exec "$SNAP/test_relexepath" $*\n')
        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
        with open(os.path.join(snapdir, relative_exe_path), 'r') as exe:
            self.assertEqual(exe_contents, exe.read())
Exemplo n.º 35
0
def _write_wrap_exe(wrapexec, wrappath, shebang=None, args=None, cwd=None):
    args = ' '.join(args) + ' $*' if args else '$*'
    cwd = 'cd {}'.format(cwd) if cwd else ''

    snap_dir = common.get_snapdir()
    assembled_env = common.assemble_env().replace(snap_dir, '$SNAP_APP_PATH')
    replace_path = r'{}/[a-z0-9][a-z0-9+-]*/install'.format(
        common.get_partsdir())
    assembled_env = re.sub(replace_path, '$SNAP_APP_PATH', assembled_env)
    executable = '"{}"'.format(wrapexec)
    if shebang is not None:
        new_shebang = re.sub(replace_path, '$SNAP_APP_PATH', shebang)
        if new_shebang != shebang:
            # If the shebang was pointing to and executable within the
            # local 'parts' dir, have the wrapper script execute it
            # directly, since we can't use $SNAP_APP_PATH in the shebang
            # itself.
            executable = '"{}" "{}"'.format(new_shebang, wrapexec)
    script = ('#!/bin/sh\n' + '{}\n'.format(assembled_env) +
              '{}\n'.format(cwd) + 'exec {} {}\n'.format(executable, args))

    with open(wrappath, 'w+') as f:
        f.write(script)

    os.chmod(wrappath, 0o755)
Exemplo n.º 36
0
    def test_wrap_exe_writes_wrapper_with_basename(self, mock_assemble_env):
        mock_assemble_env.return_value = """\
PATH={0}/part1/install/usr/bin:{0}/part1/install/bin
""".format(common.get_partsdir())

        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        open(os.path.join(snapdir, relative_exe_path), 'w').close()

        relative_wrapper_path = meta._wrap_exe(relative_exe_path,
                                               basename='new-name')
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        self.assertEqual(relative_wrapper_path, 'new-name.wrapper')

        expected = ('#!/bin/sh\n'
                    'PATH=$SNAP/usr/bin:$SNAP/bin\n'
                    '\n\n'
                    'exec "$SNAP/test_relexepath" $*\n')
        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
Exemplo n.º 37
0
    def test_wrap_exe_must_write_wrapper(self, mock_assemble_env):
        mock_assemble_env.return_value = """\
PATH={0}/part1/install/usr/bin:{0}/part1/install/bin
""".format(common.get_partsdir())

        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        open(os.path.join(snapdir, relative_exe_path), 'w').close()

        # Check that the wrapper is created even if there is already a file
        # with the same name.
        open(os.path.join('snap', 'test_relexepath.wrapper'), 'w').close()

        relative_wrapper_path = meta._wrap_exe(relative_exe_path)
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        expected = ('#!/bin/sh\n'
                    'PATH=$SNAP/usr/bin:$SNAP/bin\n'
                    '\n\n'
                    'exec "$SNAP/test_relexepath" $*\n')

        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
Exemplo n.º 38
0
    def test_clean_all_when_all_parts_specified(self):
        self.make_snapcraft_yaml(n=3)

        clean.main(['clean0', 'clean1', 'clean2'])

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemplo n.º 39
0
    def test_clean_all(self):
        self.make_snapcraft_yaml(n=3)

        clean.main()

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemplo n.º 40
0
    def test_clean_all(self):
        self.make_snapcraft_yaml(n=3)

        clean.main()

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemplo n.º 41
0
    def test_clean_all_when_all_parts_specified(self):
        self.make_snapcraft_yaml(n=3)

        clean.main(['clean0', 'clean1', 'clean2'])

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemplo n.º 42
0
    def snap_env(self):
        root = common.get_snapdir()
        env = []

        env += self.runtime_env(root)
        for part in self.all_parts:
            env += part.env(root)

        return env
Exemplo n.º 43
0
    def snap_env(self):
        snapdir = common.get_snapdir()
        env = []

        env += _runtime_env(snapdir)
        for part in self.all_parts:
            env += part.env(snapdir)

        return env
Exemplo n.º 44
0
    def snap_env(self):
        snapdir = common.get_snapdir()
        env = []

        env += _runtime_env(snapdir)
        for part in self.all_parts:
            env += part.env(snapdir)

        return env
Exemplo n.º 45
0
    def test_no_parts_defined(self):
        self.fake_config.all_parts = []

        self.mock_load_config.return_value = self.fake_config

        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
Exemplo n.º 46
0
def clean(args):
    config = _load_config()

    for part in config.all_parts:
        logger.info('Cleaning up for part %r', part.name)
        if os.path.exists(part.partdir):
            shutil.rmtree(part.partdir)

    # parts dir does not contain only generated code.
    if (os.path.exists(common.get_partsdir()) and
            not os.listdir(common.get_partsdir())):
        os.rmdir(common.get_partsdir())

    logger.info('Cleaning up staging area')
    if os.path.exists(common.get_stagedir()):
        shutil.rmtree(common.get_stagedir())

    logger.info('Cleaning up snapping area')
    if os.path.exists(common.get_snapdir()):
        shutil.rmtree(common.get_snapdir())
Exemplo n.º 47
0
    def test_command_does_not_exist(self):
        snap_dir = common.get_snapdir()
        common.env = ['PATH={}/bin:$PATH'.format(snap_dir)]

        os.mkdir(snap_dir)
        apps = {'app1': {'command': 'command-does-not-exist'}}

        with self.assertRaises(EnvironmentError) as raised:
            meta._wrap_apps(apps)
        self.assertEqual(
            "The specified command 'command-does-not-exist' defined in 'app1' "
            "does not exist or is not executable", str(raised.exception))
Exemplo n.º 48
0
    def test_strip_one_part_only_from_3(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml(n=3)

        strip.main([
            'strip1',
        ])

        self.assertFalse(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'package.yaml')),
            'There should not be a package.yaml')
        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the strip1 part')
        self.assertTrue(os.path.exists(parts[1]['state_file']),
                        'Expected a state file for the strip1 part')

        with open(parts[1]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(
            len(state), 1, 'Expected only one line in the state '
            'file for the strip1 part')
        self.assertEqual(
            state[0], 'strip', "Expected the state file for "
            " strip1 to be 'strip'")

        for i in [0, 2]:
            self.assertFalse(os.path.exists(parts[i]['part_dir']),
                             'Pulled wrong part')
            self.assertFalse(
                os.path.exists(parts[i]['state_file']),
                'Expected for only to be a state file for build1')
Exemplo n.º 49
0
def snap(args):
    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)
Exemplo n.º 50
0
    def test_exe_is_in_path(self, run_mock):
        snapdir = common.get_snapdir()
        app_path = os.path.join(snapdir, 'bin', 'app1')
        os.makedirs(os.path.dirname(app_path))
        open(app_path, 'w').close()

        relative_wrapper_path = meta._wrap_exe('app1')
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        expected = ('#!/bin/sh\n' '\n\n' 'exec "app1" $*\n')
        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
Exemplo n.º 51
0
def create(config_data):
    """Create snap.yaml and necessary package hooks.
    Create  the meta directory and provision it with snap.yaml and hooks
    in the snap dir using information from config_data.

    :param dict config_data: project values defined in snapcraft.yaml.
    :return: meta_dir.
    """
    meta_dir = os.path.join(common.get_snapdir(), 'meta')
    os.makedirs(meta_dir, exist_ok=True)

    _write_snap_yaml(meta_dir, config_data)
    _setup_assets(meta_dir, config_data)

    return meta_dir
Exemplo n.º 52
0
    def test_command_is_not_executable(self):
        snap_dir = common.get_snapdir()
        common.env = ['PATH={}/bin:$PATH'.format(snap_dir)]

        apps = {'app1': {'command': 'command-not-executable'}}

        cmd_path = os.path.join(snap_dir, 'bin', apps['app1']['command'])
        os.makedirs(os.path.dirname(cmd_path))
        open(cmd_path, 'w').close()

        with self.assertRaises(EnvironmentError) as raised:
            meta._wrap_apps(apps)
        self.assertEqual(
            "The specified command 'command-not-executable' defined in 'app1' "
            "does not exist or is not executable", str(raised.exception))
Exemplo n.º 53
0
def _write_wrap_exe(wrapexec, wrappath, args=[], cwd=None):
    args = ' '.join(args) + ' $*' if args else '$*'
    cwd = 'cd {}'.format(cwd) if cwd else ''

    snap_dir = common.get_snapdir()
    assembled_env = common.assemble_env().replace(snap_dir, '$SNAP_APP_PATH')
    replace_path = r'{}/.*/install'.format(common.get_partsdir())
    assembled_env = re.sub(replace_path, '$SNAP_APP_PATH', assembled_env)
    script = ('#!/bin/sh\n' + '{}\n'.format(assembled_env) +
              '{}\n'.format(cwd) + 'exec "{}" {}\n'.format(wrapexec, args))

    with open(wrappath, 'w+') as f:
        f.write(script)

    os.chmod(wrappath, 0o755)
Exemplo n.º 54
0
    def test_everything_is_clean(self):
        self.mock_exists.return_value = False
        self.mock_listdir.side_effect = FileNotFoundError()

        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call('partdir1'),
            mock.call('partdir2'),
            mock.call('partdir3'),
            mock.call(common.get_partsdir()),
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.assertFalse(self.mock_rmdir.called)
        self.assertFalse(self.mock_rmtree.called)
Exemplo n.º 55
0
    def test_command_found(self):
        snap_dir = common.get_snapdir()
        common.env = ['PATH={}/bin:$PATH'.format(snap_dir)]

        apps = {'app1': {'command': 'command-executable'}}

        cmd_path = os.path.join(snap_dir, 'bin', apps['app1']['command'])
        os.makedirs(os.path.dirname(cmd_path))
        open(cmd_path, 'w').close()
        os.chmod(cmd_path, 0o755)

        wrapped_apps = meta._wrap_apps(apps)

        self.assertEqual(wrapped_apps,
                         {'app1': {
                             'command': 'command-app1.wrapper'
                         }})
Exemplo n.º 56
0
    def test_wrap_exe_must_write_wrapper(self):
        snapdir = common.get_snapdir()
        os.mkdir(snapdir)

        relative_exe_path = 'test_relexepath'
        with open(os.path.join(snapdir, relative_exe_path), 'w'):
            pass

        relative_wrapper_path = meta._wrap_exe(relative_exe_path)
        wrapper_path = os.path.join(snapdir, relative_wrapper_path)

        expected = ('#!/bin/sh\n'
                    '\n\n'
                    'exec "$SNAP_APP_PATH/test_relexepath" $*\n')
        with open(wrapper_path) as wrapper_file:
            wrapper_contents = wrapper_file.read()

        self.assertEqual(expected, wrapper_contents)
Exemplo n.º 57
0
def main(argv=None):
    argv = argv if argv else []
    args = docopt(__doc__, argv=argv)

    if args['DIRECTORY']:
        # TODO: migrate to meta/snap.yaml
        # TODO: write integration test
        snap_dir = os.path.abspath(args['DIRECTORY'])
        snap = _snap_data_from_dir(snap_dir)
    else:
        # make sure the full lifecycle is executed
        snap_dir = common.get_snapdir()
        snap = lifecycle.execute('strip')

    snap_name = _format_snap_name(snap)

    logger.info('Snapping {}'.format(snap_name))
    subprocess.check_call(
        ['mksquashfs', snap_dir, snap_name, '-noappend', '-comp', 'xz'])
    logger.info('Snapped {}'.format(snap_name))
Exemplo n.º 58
0
def cmd(args):
    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)