예제 #1
0
    def handle(self, *args, **options):
        # Check the archive
        archive = options['archive'][0]
        if not os.path.isfile(archive):
            raise CommandError('%s is not a valid project archive' % archive)

        # Get the name of the project that we are importing
        project_name = options.get('project_name')
        if not project_name:
            project_name = _get_project_name(archive)

        logger.info('Importing project \'%s\' from %s', project_name, archive)

        # Check if a project with that name already exists
        project_path = self.projects_path(project_name)
        if os.path.isdir(project_path):
            if options['force']:
                logger.info('\'%s\' already exists - removing', project_name)
                shutil.rmtree(self.projects_path(project_name))
            else:
                raise CommandError('\'%s\' already exists. Either remove this '
                                   'project or use the force option' % project_name)

        _decompress_archive(archive, project_path)

        # Rewrite all of the exported files to fix their S2E environment paths
        logger.info('Rewriting project files')
        rewrite_files(project_path, CONSTANTS['import_export']['project_files'],
                      S2E_ENV_PLACEHOLDER, self.env_path())

        with open(os.path.join(project_path, 'project.json'), 'r') as f:
            proj_desc = json.load(f)

            if 'image' not in proj_desc:
                logger.error('No image description found in project.json. Unable '
                             'to determine the guest tools to symlink')
                return

            override_image = options.get('image', None)
            if override_image:
                dn = os.path.dirname(proj_desc['image'])
                old_image = os.path.basename(proj_desc['image'])
                proj_desc['image'] = os.path.join(dn, override_image)

                rewrite_files(project_path, CONSTANTS['import_export']['project_files'],
                              old_image, override_image)

            image = get_image_descriptor(proj_desc['image'])

            # Create a symlink to the guest tools directory
            self._symlink_guest_tools(project_path, image)

            # Create a symlink to guestfs (if it exists)
            if proj_desc.get('has_guestfs'):
                self._symlink_guestfs(project_path, image)

        logger.success('Project successfully imported from %s to %s', archive, project_path)
예제 #2
0
    def handle(self, *args, **options):
        # Check the archive
        archive = options['archive'][0]
        if not os.path.isfile(archive):
            raise CommandError('%s is not a valid project archive' % archive)

        # Get the name of the project that we are importing
        project_name = _get_project_name(archive)
        logger.info('Importing project \'%s\' from %s', project_name, archive)

        # Check if a project with that name already exists
        project_path = self.projects_path(project_name)
        if os.path.isdir(project_path):
            if options['force']:
                logger.info('\'%s\' already exists - removing', project_name)
                shutil.rmtree(self.projects_path(project_name))
            else:
                raise CommandError('\'%s\' already exists. Either remove this '
                                   'project or use the force option' % project_name)

        # Decompress the archive
        self._decompress_archive(archive)

        # Rewrite all of the exported files to fix their S2E environment paths
        logger.info('Rewriting project files')
        rewrite_files(project_path, CONSTANTS['import_export']['project_files'],
                      S2E_ENV_PLACEHOLDER, self.env_path())

        with open(os.path.join(project_path, 'project.json'), 'r') as f:
            proj_desc = json.load(f)

            # Create a symlink to the guest tools directory
            self._symlink_guest_tools(project_path, proj_desc)

            # Create a symlink to guestfs (if it exists)
            if proj_desc.get('has_guestfs'):
                self._symlink_guestfs(project_path, proj_desc)

        logger.success('Project successfully imported from %s', archive)
예제 #3
0
    def handle(self, *args, **options):
        # Name the project archive if it doesn't already have a name
        output_path = options['output_path']
        if not output_path:
            output_path = self.env_path('%s.tar.xz' % self.project_name)

        with TemporaryDirectory() as temp_dir:
            # Store all of the exported files in a temporary directory so that
            # we can just execute tar on the entire directory
            export_dir = os.path.join(temp_dir, self.project_name)

            # Do **not** export these files
            blacklist = CONSTANTS['import_export']['blacklist']
            if not options['export_results']:
                blacklist.extend(['s2e-last', 's2e-out-*'])

            # Copy the project directory
            logger.info('Copying project %s', self.project_name)
            shutil.copytree(self.project_path(),
                            export_dir,
                            ignore=shutil.ignore_patterns(*blacklist))

            # Rewrite certain project files (e.g., launch-s2e.sh, etc.) to
            # remove the absolute path to the current S2E environment. This
            # path is replaced with a placeholder token which is then rewritten
            # with the absolute path of the new S2E environment when the
            # project is imported
            logger.info('Rewriting project files')
            rewrite_files(export_dir,
                          CONSTANTS['import_export']['project_files'],
                          self.env_path(), S2E_ENV_PLACEHOLDER)

            # Update project.json
            #
            # project.json has already had its S2E environment path
            # overwritten. However, there are still other paths that need
            # rewriting to ensure that the project can be correctly imported.
            logger.info('Updating project.json')
            with open(os.path.join(export_dir, 'project.json'), 'r+') as f:
                proj_desc = json.load(f)

                # The target files in a project are normally symbolic links.
                # However, when exported they are no longer symbolic links and
                # so we must update their paths

                proj_path = proj_desc['project_dir']
                update_path = lambda p: os.path.join(proj_path,
                                                     os.path.basename(p))

                target_path = proj_desc.get('target_path')
                if target_path:
                    proj_desc['target_path'] = update_path(target_path)

                target_files = proj_desc.get('target_files')
                if target_files:
                    proj_desc['target_files'] = [
                        update_path(tf) for tf in target_files
                    ]

                # Update the project.json in the temporary directory
                proj_desc_json = json.dumps(proj_desc,
                                            sort_keys=True,
                                            indent=4)
                f.seek(0)
                f.write(proj_desc_json)
                f.truncate()

            # Create the archive of the temporary directory's contents
            self._create_archive(output_path, temp_dir)

        logger.success('Project successfully exported to %s', output_path)