Esempio n. 1
0
    def setUp(self):
        super().setUp()

        self.config_data = {
            'architectures': ['amd64'],
            'name': 'my-package',
            'version': '1.0',
            'description': 'my description',
            'summary': 'my summary',
            'confinement': 'devmode',
            'environment': {
                'GLOBAL': 'y',
            },
            'parts': {
                'test-part': {
                    'plugin': 'nil',
                }
            }
        }

        patcher = patch('snapcraft.internal.project_loader.get_snapcraft_yaml')
        self.mock_get_yaml = patcher.start()
        self.mock_get_yaml.return_value = os.path.join('snap',
                                                       'snapcraft.yaml')
        self.addCleanup(patcher.stop)

        # Ensure the ensure snapcraft.yaml method has something to copy.
        _create_file(os.path.join('snap', 'snapcraft.yaml'))

        self.meta_dir = os.path.join(self.prime_dir, 'meta')
        self.hooks_dir = os.path.join(self.meta_dir, 'hooks')
        self.snap_yaml = os.path.join(self.meta_dir, 'snap.yaml')

        self.project_options = ProjectOptions()
Esempio n. 2
0
    def setUp(self):
        super().setUp()

        # TODO move to use outer interface
        self.packager = _snap_packaging._SnapPackaging(
            {'confinement': 'devmode'}, ProjectOptions(), 'dummy')
        self.packager._is_host_compatible_with_base = True
Esempio n. 3
0
    def test_cleanbuild(self, mock_pet):
        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        mock_pet.return_value = 'my-pet'

        project_options = ProjectOptions()
        lxd.Cleanbuilder('snap.snap', 'project.tar', project_options).execute()
        expected_arch = project_options.deb_arch

        self.assertEqual(
            'Setting up container with project assets\n'
            'Copying snapcraft cache into container\n'
            'Waiting for a network connection...\n'
            'Network connection established\n'
            'Retrieved snap.snap\n', fake_logger.output)

        self.check_call_mock.assert_has_calls([
            call([
                'lxc', 'launch', '-e',
                'ubuntu:xenial/{}'.format(expected_arch),
                'local:snapcraft-my-pet'
            ]),
            call([
                'lxc', 'config', 'set', 'local:snapcraft-my-pet',
                'environment.SNAPCRAFT_SETUP_CORE', '1'
            ]),
            call([
                'lxc', 'file', 'push', 'project.tar',
                'local:snapcraft-my-pet//root/project.tar'
            ]),
            call([
                'lxc', 'exec', 'local:snapcraft-my-pet', '--', 'tar', 'xvf',
                '/root/project.tar'
            ]),
            call([
                'lxc', 'exec', 'local:snapcraft-my-pet', '--', 'python3', '-c',
                'import urllib.request; '
                'urllib.request.urlopen('
                '"http://start.ubuntu.com/connectivity-check.html", '
                'timeout=5)'
            ]),
            call([
                'lxc', 'exec', 'local:snapcraft-my-pet', '--', 'apt-get',
                'update'
            ]),
            call([
                'lxc', 'exec', 'local:snapcraft-my-pet', '--', 'apt-get',
                'install', 'snapcraft', '-y'
            ]),
            call([
                'lxc', 'exec', 'local:snapcraft-my-pet', '--', 'snapcraft',
                'snap', '--output', 'snap.snap'
            ]),
            call([
                'lxc', 'file', 'pull',
                'local:snapcraft-my-pet//root/snap.snap', 'snap.snap'
            ]),
            call(['lxc', 'stop', '-f', 'local:snapcraft-my-pet']),
        ])
Esempio n. 4
0
    def test_user_agent_darwin(self):
        arch = ProjectOptions().deb_arch
        expected = f"snapcraft/{snapcraft_version} Darwin ({arch})"

        self.expectThat(
            storeapi._agent.get_user_agent(platform="darwin"), Equals(expected)
        )
Esempio n. 5
0
    def test_user_agent_linux_unknown(self):
        self.useFixture(FakeOsRelease(name=None, version_id=None))

        arch = ProjectOptions().deb_arch
        expected = f"snapcraft/{snapcraft_version} Unknown/Unknown Version ({arch})"

        self.expectThat(storeapi._agent.get_user_agent("linux"), Equals(expected))
Esempio n. 6
0
    def test_cleanbuild_with_remote(self, mock_pet):
        mock_pet.return_value = 'my-pet'

        project_options = ProjectOptions()
        lxd.Cleanbuilder('snap.snap', 'project.tar', project_options,
                         remote='my-remote').execute()
        expected_arch = project_options.deb_arch

        self.check_call_mock.assert_has_calls([
            call(['lxc', 'launch', '-e',
                  'ubuntu:xenial/{}'.format(expected_arch),
                  'my-remote:snapcraft-my-pet']),
            call(['lxc', 'config', 'set', 'my-remote:snapcraft-my-pet',
                  'environment.SNAPCRAFT_SETUP_CORE', '1']),
            call(['lxc', 'file', 'push', 'project.tar',
                  'my-remote:snapcraft-my-pet//root/project.tar']),
            call(['lxc', 'exec', 'my-remote:snapcraft-my-pet', '--',
                  'tar', 'xvf', '/root/project.tar']),
            call(['lxc', 'exec', 'my-remote:snapcraft-my-pet', '--',
                  'python3', '-c',
                  'import urllib.request; '
                  'urllib.request.urlopen('
                  '"http://start.ubuntu.com/connectivity-check.html", '
                  'timeout=5)']),
            call(['lxc', 'exec', 'my-remote:snapcraft-my-pet', '--',
                  'apt-get', 'update']),
            call(['lxc', 'exec', 'my-remote:snapcraft-my-pet', '--',
                  'apt-get', 'install', 'snapcraft', '-y']),
            call(['lxc', 'exec', 'my-remote:snapcraft-my-pet', '--',
                  'snapcraft', 'snap', '--output', 'snap.snap']),
            call(['lxc', 'file', 'pull',
                  'my-remote:snapcraft-my-pet//root/snap.snap',
                  'snap.snap']),
            call(['lxc', 'stop', '-f', 'my-remote:snapcraft-my-pet']),
        ])
Esempio n. 7
0
    def test_user_agent_linux(self):
        self.useFixture(FakeOsRelease())

        arch = ProjectOptions().deb_arch
        expected = f"snapcraft/{snapcraft_version} Ubuntu/16.04 ({arch})"

        self.expectThat(storeapi._agent.get_user_agent("linux"), Equals(expected))
Esempio n. 8
0
 def test_output_set_correctly(self):
     project = ProjectOptions()
     instance = lxd.Containerbuild(project_options=project,
                                   source='tarball.tgz',
                                   metadata=self.snap,
                                   container_name='name')
     self.assertThat(instance._snap_output, Equals(self.expected))
Esempio n. 9
0
 def setUp(self):
     super().setUp()
     self.fake_lxd = tests.fixture_setup.FakeLXD()
     self.useFixture(self.fake_lxd)
     self.fake_logger = fixtures.FakeLogger(level=logging.INFO)
     self.useFixture(self.fake_logger)
     self.project_options = ProjectOptions(target_deb_arch=self.target_arch)
Esempio n. 10
0
    def setUp(self):
        super().setUp()

        self.fake_elf = fixture_setup.FakeElf(root_path=self.path)
        self.useFixture(self.fake_elf)
        self.content_dirs = []
        self.arch_triplet = ProjectOptions().arch_triplet
Esempio n. 11
0
def get_project_options(**kwargs):
    project_args = dict(
        use_geoip=kwargs.pop('enable_geoip'),
        parallel_builds=not kwargs.pop('no_parallel_builds'),
        target_deb_arch=kwargs.pop('target_arch'),
    )

    return ProjectOptions(**project_args)
Esempio n. 12
0
    def test_cleanbuild(self, mock_pet):
        fake_lxd = tests.fixture_setup.FakeLXD()
        self.useFixture(fake_lxd)
        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        mock_pet.return_value = 'my-pet'

        project_options = ProjectOptions()
        metadata = {'name': 'project'}
        project_folder = 'build_project'
        lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                         metadata=metadata, remote=self.remote,
                         project_options=project_options).execute()
        expected_arch = project_options.deb_arch

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

        container_name = '{}:snapcraft-my-pet'.format(self.remote)
        fake_lxd.check_call_mock.assert_has_calls([
            call(['lxc', 'launch', '-e',
                  'ubuntu:xenial/{}'.format(expected_arch), container_name]),
            call(['lxc', 'config', 'set', container_name,
                  'environment.SNAPCRAFT_SETUP_CORE', '1']),
            call(['lxc', 'exec', container_name,
                  '--env', 'HOME=/{}'.format(project_folder), '--',
                  'mkdir', project_folder]),
            call(['lxc', 'file', 'push', os.path.realpath('project.tar'),
                  '{}/build_project/project.tar'.format(container_name)]),
            call(['lxc', 'exec', container_name,
                  '--env', 'HOME=/{}'.format(project_folder), '--',
                  'tar', 'xvf', 'project.tar']),
            call(['lxc', 'exec', container_name,
                  '--env', 'HOME=/{}'.format(project_folder), '--',
                  'python3', '-c',
                  'import urllib.request; '
                  'urllib.request.urlopen('
                  '"http://start.ubuntu.com/connectivity-check.html", '
                  'timeout=5)']),
            call(['lxc', 'exec', container_name,
                  '--env', 'HOME=/{}'.format(project_folder), '--',
                  'apt-get', 'update']),
            call(['lxc', 'exec', container_name,
                  '--env', 'HOME=/{}'.format(project_folder), '--',
                  'apt-get', 'install', 'snapcraft', '-y']),
            call(['lxc', 'exec', container_name,
                  '--env', 'HOME=/{}'.format(project_folder), '--',
                  'snapcraft', 'snap', '--output', 'snap.snap']),
            call(['lxc', 'file', 'pull',
                  '{}/{}/snap.snap'.format(container_name, project_folder),
                  'snap.snap']),
            call(['lxc', 'stop', '-f', container_name]),
        ])
Esempio n. 13
0
    def test_remote_does_not_exist(self, mock_sleep, mock_run):
        self.check_output_mock.side_effect = check_output_side_effect(
              fail_on_remote=True)

        project_options = ProjectOptions(debug=False)
        with ExpectedException(lxd.SnapcraftEnvironmentError,
                               'There are either.*my-remote.*'):
            lxd.Cleanbuilder('snap.snap', 'project.tar',
                             project_options, remote='my-remote')
Esempio n. 14
0
    def setUp(self):
        super().setUp()

        # TODO move to use outer interface
        self.packager = _snap_packaging._SnapPackaging(
            {'confinement': 'devmode'},
            ProjectOptions(),
            'dummy'
        )
Esempio n. 15
0
    def test_download_from_branded_store_requires_login(self):
        err = self.assertRaises(errors.SnapNotFoundError, self.client.download,
                                'test-snap-branded-store', 'test-channel',
                                'dummy')

        arch = ProjectOptions().deb_arch
        self.assertEqual(
            "Snap 'test-snap-branded-store' for '{}' cannot be found in "
            "the 'test-channel' channel.".format(arch), str(err))
Esempio n. 16
0
 def test_user_agent(self):
     arch = ProjectOptions().deb_arch
     expected_pre = 'snapcraft/{} '.format(snapcraft_version)
     expected_post = ' {} ({})'.format(
         '/'.join(platform.dist()[0:2]),  # i.e. Ubuntu/16.04
         arch,
     )
     actual = storeapi._agent.get_user_agent()
     self.assertTrue(actual.startswith(expected_pre))
     self.assertTrue(actual.endswith(expected_post))
Esempio n. 17
0
    def test_cleanbuild(self, mock_pet, mock_inject, mock_container_run):
        mock_container_run.side_effect = lambda cmd, **kwargs: cmd
        fake_lxd = tests.fixture_setup.FakeLXD()
        self.useFixture(fake_lxd)
        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        mock_pet.return_value = 'my-pet'
        project_options = ProjectOptions(target_deb_arch=self.target_arch)
        metadata = {'name': 'project'}
        project_folder = '/root/build_project'
        lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                         metadata=metadata, remote=self.remote,
                         project_options=project_options).execute()
        expected_arch = 'amd64'

        self.assertIn('Setting up container with project assets\n'
                      'Waiting for a network connection...\n'
                      'Network connection established\n'
                      'Retrieved snap.snap\n', fake_logger.output)
        args = []
        if self.target_arch:
            self.assertIn('Setting target machine to \'{}\'\n'.format(
                          self.target_arch), fake_logger.output)
            args += ['--target-arch', self.target_arch]

        container_name = '{}:snapcraft-my-pet'.format(self.remote)
        fake_lxd.check_call_mock.assert_has_calls([
            call(['lxc', 'launch', '-e',
                  'ubuntu:xenial/{}'.format(expected_arch), container_name]),
            call(['lxc', 'config', 'set', container_name,
                  'environment.SNAPCRAFT_SETUP_CORE', '1']),
            call(['lxc', 'config', 'set', container_name,
                  'environment.LC_ALL', 'C.UTF-8']),
            call(['lxc', 'file', 'push', os.path.realpath('project.tar'),
                  '{}/root/build_project/project.tar'.format(container_name)]),
        ])
        mock_container_run.assert_has_calls([
            call(['mkdir', project_folder]),
            call(['tar', 'xvf', 'project.tar'],
                 cwd=project_folder),
            call(['python3', '-c', 'import urllib.request; ' +
                  'urllib.request.urlopen(' +
                  '"http://start.ubuntu.com/connectivity-check.html"' +
                  ', timeout=5)']),
            call(['apt-get', 'update']),
            call(['snapcraft', 'snap', '--output', 'snap.snap', *args],
                 cwd=project_folder),
        ])
        fake_lxd.check_call_mock.assert_has_calls([
            call(['lxc', 'file', 'pull',
                  '{}{}/snap.snap'.format(container_name, project_folder),
                  'snap.snap']),
            call(['lxc', 'stop', '-f', container_name]),
        ])
Esempio n. 18
0
    def test_remote_does_not_exist(self, mock_run):
        self.useFixture(tests.fixture_setup.FakeLXD(fail_on_remote=True))

        project_options = ProjectOptions(debug=False)
        metadata = {'name': 'project'}
        with ExpectedException(lxd.SnapcraftEnvironmentError,
                               'There are either.*my-remote.*'):
            lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                             metadata=metadata,
                             project_options=project_options,
                             remote='my-remote')
Esempio n. 19
0
    def setUp(self):
        super().setUp()
        self.fake_lxd = fixture_setup.FakeLXD()
        self.useFixture(self.fake_lxd)
        self.fake_lxd.kernel_arch = self.server
        self.fake_filesystem = fixture_setup.FakeFilesystem()
        self.useFixture(self.fake_filesystem)

        self.fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(self.fake_logger)
        self.project_options = ProjectOptions(target_deb_arch=self.target_arch)
Esempio n. 20
0
    def test_lxc_check_fails(self, mock_sleep, mock_run):
        self.check_output_mock.side_effect = check_output_side_effect(
            fail_on_default=True)

        project_options = ProjectOptions(debug=False)
        with ExpectedException(
                lxd.SnapcraftEnvironmentError,
                'You must have LXD installed in order to use cleanbuild. '
                'However, it is either not installed or not configured '
                'properly.\n'
                'Refer to the documentation at '
                'https://linuxcontainers.org/lxd/getting-started-cli.'):
            lxd.Cleanbuilder('snap.snap', 'project.tar', project_options)
Esempio n. 21
0
    def test_failed_build_with_debug(self):
        def call_effect(*args, **kwargs):
            if "snapcraft snap --output snap.snap" in " ".join(args[0]):
                raise CalledProcessError(returncode=255, cmd=args[0])
            return self.fake_lxd.check_output_side_effect()(*args, **kwargs)

        self.fake_lxd.check_call_mock.side_effect = call_effect

        self.project_options = ProjectOptions(debug=True)
        self.make_containerbuild().execute()

        self.fake_lxd.check_call_mock.assert_has_calls(
            [call(["lxc", "exec", self.fake_lxd.name, "--", "bash", "-i"])])
Esempio n. 22
0
    def test_remote_does_not_exist(self, mock_run):
        fake_lxd = tests.fixture_setup.FakeLXD()
        self.useFixture(fake_lxd)
        fake_lxd.check_output_mock.side_effect = CalledProcessError(
            255, ['lxd', 'list', 'my-remote'])

        project_options = ProjectOptions(debug=False)
        metadata = {'name': 'project'}
        with ExpectedException(lxd.SnapcraftEnvironmentError,
                               'There are either.*my-remote.*'):
            lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                             metadata=metadata,
                             project_options=project_options,
                             remote='my-remote')
Esempio n. 23
0
def get_project_options(**kwargs):
    ctx = click.get_current_context()
    for key, value in ctx.parent.params.items():
        if not kwargs.get(key):
            kwargs[key] = value

    project_args = dict(
        debug=kwargs.pop('debug'),
        use_geoip=kwargs.pop('enable_geoip'),
        parallel_builds=not kwargs.pop('no_parallel_builds'),
        target_deb_arch=kwargs.pop('target_arch'),
    )

    return ProjectOptions(**project_args)
Esempio n. 24
0
    def test_failed_build_with_debug(self, mock_sleep, mock_run):
        call_list = []

        def run_effect(*args, **kwargs):
            call_list.append(args[0])
            if args[0] == ['snapcraft', 'snap', '--output', 'snap.snap']:
                raise CalledProcessError(returncode=255, cmd=args[0])

        mock_run.side_effect = run_effect

        project_options = ProjectOptions(debug=True)
        lxd.Cleanbuilder('snap.snap', 'project.tar', project_options).execute()

        self.assertIn(['bash', '-i'], call_list)
Esempio n. 25
0
    def test_failed_build_with_debug(self):
        def call_effect(*args, **kwargs):
            if 'snapcraft snap --output snap.snap' in ' '.join(args[0]):
                raise CalledProcessError(returncode=255, cmd=args[0])
            return self.fake_lxd.check_output_side_effect()(*args, **kwargs)

        self.fake_lxd.check_call_mock.side_effect = call_effect

        self.project_options = ProjectOptions(debug=True)
        self.make_containerbuild().execute()

        self.fake_lxd.check_call_mock.assert_has_calls([
            call(['lxc', 'exec', self.fake_lxd.name, '--', 'bash', '-i']),
        ])
Esempio n. 26
0
    def test_lxc_check_fails(self, mock_run):
        fake_lxd = tests.fixture_setup.FakeLXD()
        self.useFixture(fake_lxd)
        fake_lxd.check_output_mock.side_effect = FileNotFoundError('lxc')

        project_options = ProjectOptions(debug=False)
        metadata = {'name': 'project'}
        with ExpectedException(
                lxd.SnapcraftEnvironmentError,
                'You must have LXD installed in order to use cleanbuild.\n'
                'Refer to the documentation at '
                'https://linuxcontainers.org/lxd/getting-started-cli.'):
            lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                             metadata=metadata,
                             project_options=project_options)
Esempio n. 27
0
    def test_lxc_check_fails(self, mock_run):
        self.useFixture(tests.fixture_setup.FakeLXD(fail_on_default=True))

        project_options = ProjectOptions(debug=False)
        metadata = {'name': 'project'}
        with ExpectedException(
                lxd.SnapcraftEnvironmentError,
                'You must have LXD installed in order to use cleanbuild. '
                'However, it is either not installed or not configured '
                'properly.\n'
                'Refer to the documentation at '
                'https://linuxcontainers.org/lxd/getting-started-cli.'):
            lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                             metadata=metadata,
                             project_options=project_options)
Esempio n. 28
0
    def test_failed_build_with_debug(self, mock_run):
        self.useFixture(tests.fixture_setup.FakeLXD())
        call_list = []

        def run_effect(*args, **kwargs):
            call_list.append(args[0])
            if args[0] == ['snapcraft', 'snap', '--output', 'snap.snap']:
                raise CalledProcessError(returncode=255, cmd=args[0])

        mock_run.side_effect = run_effect

        project_options = ProjectOptions(debug=True)
        metadata = {'name': 'project'}
        lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                         metadata=metadata,
                         project_options=project_options).execute()

        self.assertIn(['bash', '-i'], call_list)
Esempio n. 29
0
    def __init__(
        self,
        *,
        elf_files: FrozenSet[elf.ElfFile],
        plugin,
        project: ProjectOptions,
        confinement: str,  # TODO remove once project has this
        core_base: str,  # TODO remove once project has this
        snap_base_path: str,  # TODO remove once project has this
        stage_packages: List[str],
        stagedir: str,
        primedir: str
    ) -> None:
        """Initialize PartPatcher.

        :param elf_files: the list of elf files to analyze.
        :param plugin: the plugin the part is using.
        :param project: the project instance from the part.
        :param confinement: the confinement value the snapcraft project is
                            using (i.e.; devmode, strict, classic).
        :param core_base: the base the snap will use during runtime
                          (e.g.; core, core18).
        :param snap_base_path: the root path of the snap during runtime,
                               necessary when using a in-snap libc6 provided
                               as a stage-packages entry.
        :param stage_packages: the stage-packages a part is set to use.
        :param stagedir: the general stage directory for the snapcraft project.
                         This is used to locate an alternate patchelf binary
                         to use.
        :param primedir: the general prime directory for the snapcraft project.
        """
        self._elf_files = elf_files
        self._is_go_based_plugin = is_go_based_plugin(plugin)
        self._project = project
        self._is_classic = confinement == "classic"
        self._is_host_compat_with_base = project.is_host_compatible_with_base(core_base)
        self._core_base = core_base
        self._snap_base_path = snap_base_path
        # If libc6 is staged, to avoid symbol mixups we will resort to
        # glibc mangling.
        self._is_libc6_staged = "libc6" in stage_packages
        self._stagedir = stagedir
        self._primedir = primedir
Esempio n. 30
0
    def __init__(
            self,
            *,
            elf_files: FrozenSet[elf.ElfFile],
            plugin,
            project: ProjectOptions,
            confinement: str,  # TODO remove once project has this
            core_base: str,  # TODO remove once project has this
            snap_base_path: str,  # TODO remove once project has this
            stage_packages: List[str],
            stagedir: str,
            primedir: str) -> None:
        """Initialize PartPatcher.

        :param elf_files: the list of elf files to analyze.
        :param plugin: the plugin the part is using.
        :param project: the project instance from the part.
        :param confinement: the confinement value the snapcraft project is
                            using (i.e.; devmode, strict, classic).
        :param core_base: the base the snap will use during runtime
                          (e.g.; core, core18).
        :param snap_base_path: the root path of the snap during runtime,
                               necessary when using a in-snap libc6 provided
                               as a stage-packages entry.
        :param stage_packages: the stage-packages a part is set to use.
        :param stagedir: the general stage directory for the snapcraft project.
                         This is used to locate an alternate patchelf binary
                         to use.
        :param primedir: the general prime directory for the snapcraft project.
        """
        self._elf_files = elf_files
        self._is_go_based_plugin = is_go_based_plugin(plugin)
        self._project = project
        self._is_classic = confinement == 'classic'
        self._is_host_compat_with_base = project.is_host_compatible_with_base(
            core_base)
        self._core_base = core_base
        self._snap_base_path = snap_base_path
        # If libc6 is staged, to avoid symbol mixups we will resort to
        # glibc mangling.
        self._is_libc6_staged = 'libc6' in stage_packages
        self._stagedir = stagedir
        self._primedir = primedir
Esempio n. 31
0
    def test_failed_container_never_created(self):
        fake_lxd = tests.fixture_setup.FakeLXD()
        self.useFixture(fake_lxd)

        def call_effect(*args, **kwargs):
            if args[0][:2] == ['lxc', 'launch']:
                raise CalledProcessError(returncode=255, cmd=args[0])
            return fake_lxd.check_output_side_effect()(*args, **kwargs)

        fake_lxd.check_call_mock.side_effect = call_effect

        metadata = {'name': 'project'}
        raised = self.assertRaises(
            CalledProcessError,
            lxd.Cleanbuilder(output='snap.snap', source='project.tar',
                             metadata=metadata,
                             project_options=ProjectOptions()).execute)
        self.assertEquals(fake_lxd.status, None)
        # lxc launch should fail and no further commands should come after that
        self.assertThat(str(raised), Contains("Command '['lxc', 'launch'"))