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)
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)
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)