<s> from __future__ import print_function <EOL> from __future__ import unicode_literals <EOL> from collections import defaultdict <EOL> import glob <EOL> import logging <EOL> import os <EOL> import re <EOL> import subprocess <EOL> import tempfile <EOL> import time <EOL> from imagemounter import _util , BLOCK_SIZE <EOL> from imagemounter . volume_system import VolumeSystem <EOL> logger = logging . getLogger ( __name__ ) <EOL> class Disk ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parser , path , offset = <NUM_LIT:0> , read_write = False , method = '<STR_LIT>' , <EOL> multifile = True , index = None , mount_directories = True , ** args ) : <EOL> """<STR_LIT>""" <EOL> self . parser = parser <EOL> path = os . path . expandvars ( os . path . expanduser ( path ) ) <EOL> if _util . is_encase ( path ) : <EOL> self . type = '<STR_LIT>' <EOL> elif _util . is_vmware ( path ) : <EOL> self . type = '<STR_LIT>' <EOL> elif _util . is_compressed ( path ) : <EOL> self . type = '<STR_LIT>' <EOL> else : <EOL> self . type = '<STR_LIT>' <EOL> self . paths = sorted ( _util . expand_path ( path ) ) <EOL> self . offset = offset <EOL> self . block_size = BLOCK_SIZE <EOL> self . read_write = read_write <EOL> self . method = method <EOL> self . read_write = read_write <EOL> self . rwpath = "<STR_LIT>" <EOL> self . multifile = multifile <EOL> self . index = index <EOL> self . mount_directories = mount_directories <EOL> self . args = args <EOL> self . name = os . path . split ( path ) [ <NUM_LIT:1> ] <EOL> self . mountpoint = '<STR_LIT>' <EOL> self . avfs_mountpoint = '<STR_LIT>' <EOL> self . volumes = VolumeSystem ( parent = self , ** args ) <EOL> self . volume_source = "<STR_LIT>" <EOL> self . offset = <NUM_LIT:0> <EOL> self . _disktype = defaultdict ( dict ) <EOL> self . loopback = "<STR_LIT>" <EOL> self . md_device = "<STR_LIT>" <EOL> def __unicode__ ( self ) : <EOL> return self . name <EOL> def __str__ ( self ) : <EOL> return self . __unicode__ ( ) <EOL> def __getitem__ ( self , item ) : <EOL> return self . volumes [ item ] <EOL> def init ( self , single = None , raid = True , disktype = True ) : <EOL> """<STR_LIT>""" <EOL> self . mount ( ) <EOL> if raid : <EOL> self . add_to_raid ( ) <EOL> if disktype : <EOL> self . volumes . load_disktype_data ( ) <EOL> for v in self . mount_volumes ( single ) : <EOL> yield v <EOL> def mount ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . parser . casename : <EOL> self . mountpoint = tempfile . mkdtemp ( prefix = '<STR_LIT>' , suffix = '<STR_LIT:_>' + self . parser . casename ) <EOL> else : <EOL> self . mountpoint = tempfile . mkdtemp ( prefix = '<STR_LIT>' ) <EOL> if self . read_write : <EOL> self . rwpath = tempfile . mkstemp ( prefix = "<STR_LIT>" ) [ <NUM_LIT:1> ] <EOL> if self . method == '<STR_LIT>' : <EOL> methods = [ ] <EOL> def add_method_if_exists ( method ) : <EOL> if ( method == '<STR_LIT>' and _util . command_exists ( '<STR_LIT>' ) ) or _util . command_exists ( method ) : <EOL> methods . append ( method ) <EOL> if self . read_write : <EOL> add_method_if_exists ( '<STR_LIT>' ) <EOL> else : <EOL> if self . type == '<STR_LIT>' : <EOL> add_method_if_exists ( '<STR_LIT>' ) <EOL> elif self . type == '<STR_LIT>' : <EOL> add_method_if_exists ( '<STR_LIT>' ) <EOL> add_method_if_exists ( '<STR_LIT>' ) <EOL> elif self . type == '<STR_LIT>' : <EOL> add_method_if_exists ( '<STR_LIT>' ) <EOL> elif self . type == '<STR_LIT>' : <EOL> add_method_if_exists ( '<STR_LIT>' ) <EOL> add_method_if_exists ( '<STR_LIT>' ) <EOL> else : <EOL> methods = [ self . method ] <EOL> cmds = [ ] <EOL> for method in methods : <EOL> if method == '<STR_LIT>' : <EOL> self . avfs_mountpoint = tempfile . mkdtemp ( prefix = '<STR_LIT>' ) <EOL> _util . check_call_ ( [ '<STR_LIT>' , self . avfs_mountpoint , '<STR_LIT>' , '<STR_LIT>' ] , stdout = subprocess . PIPE ) <EOL> avfspath = self . avfs_mountpoint + '<STR_LIT:/>' + os . path . abspath ( self . paths [ <NUM_LIT:0> ] ) + '<STR_LIT:#>' <EOL> targetraw = os . path . join ( self . mountpoint , '<STR_LIT>' ) <EOL> os . symlink ( avfspath , targetraw ) <EOL> logger . debug ( "<STR_LIT>" . format ( avfspath , targetraw ) ) <EOL> raw_path = self . get_raw_path ( ) <EOL> logger . debug ( "<STR_LIT>" . format ( raw_path ) ) <EOL> if self . method == '<STR_LIT>' : <EOL> self . method = '<STR_LIT>' <EOL> return raw_path is not None <EOL> elif method == '<STR_LIT>' : <EOL> cmds . append ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' if self . type == '<STR_LIT>' else '<STR_LIT>' ] ) <EOL> if self . read_write : <EOL> cmds [ - <NUM_LIT:1> ] . extend ( [ '<STR_LIT>' , self . rwpath ] ) <EOL> elif method == '<STR_LIT>' : <EOL> cmds . extend ( [ [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , [ '<STR_LIT>' ] ] ) <EOL> elif method == '<STR_LIT>' : <EOL> cmds . extend ( [ [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , [ '<STR_LIT>' ] ] ) <EOL> elif method == '<STR_LIT>' : <EOL> cmds . append ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> elif method == '<STR_LIT>' : <EOL> os . rmdir ( self . mountpoint ) <EOL> self . mountpoint = "<STR_LIT>" <EOL> logger . debug ( "<STR_LIT>" . format ( self . get_raw_path ( ) ) ) <EOL> return True <EOL> else : <EOL> raise Exception ( "<STR_LIT>" . format ( self . method ) ) <EOL> for cmd in cmds [ : ] : <EOL> if self . multifile and len ( self . paths ) > <NUM_LIT:1> : <EOL> cmds . append ( cmd [ : ] ) <EOL> cmds [ - <NUM_LIT:1> ] . extend ( self . paths ) <EOL> cmds [ - <NUM_LIT:1> ] . append ( self . mountpoint ) <EOL> cmd . append ( self . paths [ <NUM_LIT:0> ] ) <EOL> cmd . append ( self . mountpoint ) <EOL> for cmd in cmds : <EOL> try : <EOL> _util . check_call_ ( cmd , stdout = subprocess . PIPE ) <EOL> time . sleep ( <NUM_LIT> ) <EOL> except Exception : <EOL> logger . warning ( '<STR_LIT>' . format ( self . paths [ <NUM_LIT:0> ] ) , exc_info = True ) <EOL> continue <EOL> else : <EOL> raw_path = self . get_raw_path ( ) <EOL> logger . debug ( "<STR_LIT>" . format ( raw_path ) ) <EOL> if self . method == '<STR_LIT>' : <EOL> self . method = cmd [ <NUM_LIT:0> ] <EOL> return raw_path is not None <EOL> logger . error ( '<STR_LIT>' . format ( self . paths [ <NUM_LIT:0> ] ) ) <EOL> os . rmdir ( self . mountpoint ) <EOL> self . mountpoint = "<STR_LIT>" <EOL> return False <EOL> def get_raw_path ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . method == '<STR_LIT>' : <EOL> return self . paths [ <NUM_LIT:0> ] <EOL> else : <EOL> if self . method == '<STR_LIT>' and os . path . isdir ( os . path . join ( self . mountpoint , '<STR_LIT>' ) ) : <EOL> logger . debug ( "<STR_LIT>" ) <EOL> searchdirs = ( os . path . join ( self . mountpoint , '<STR_LIT>' ) , self . mountpoint ) <EOL> else : <EOL> searchdirs = ( self . mountpoint , ) <EOL> raw_path = [ ] <EOL> for searchdir in searchdirs : <EOL> for pattern in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> raw_path . extend ( glob . glob ( os . path . join ( searchdir , pattern ) ) ) <EOL> if not raw_path : <EOL> logger . warning ( "<STR_LIT>" . format ( searchdirs ) ) <EOL> return None <EOL> return raw_path [ <NUM_LIT:0> ] <EOL> def get_fs_path ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . md_device : <EOL> return self . md_device <EOL> elif self . loopback : <EOL> return self . loopback <EOL> else : <EOL> return self . get_raw_path ( ) <EOL> def is_raid ( self ) : <EOL> """<STR_LIT>""" <EOL> if not _util . command_exists ( '<STR_LIT>' ) : <EOL> logger . info ( "<STR_LIT>" ) <EOL> return False <EOL> try : <EOL> result = _util . check_output_ ( [ "<STR_LIT>" , "<STR_LIT>" , self . get_raw_path ( ) ] , stderr = subprocess . STDOUT ) <EOL> for l in result . splitlines ( ) : <EOL> if '<STR_LIT>' in l : <EOL> logger . debug ( "<STR_LIT>" + l [ l . index ( '<STR_LIT::>' ) + <NUM_LIT:2> : ] ) <EOL> break <EOL> else : <EOL> return False <EOL> except Exception : <EOL> return False <EOL> return True <EOL> def add_to_raid ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . is_raid ( ) : <EOL> return False <EOL> try : <EOL> self . loopback = _util . check_output_ ( [ '<STR_LIT>' , '<STR_LIT>' ] ) . strip ( ) <EOL> except Exception : <EOL> logger . warning ( "<STR_LIT>" , exc_info = True ) <EOL> return False <EOL> cmd = [ '<STR_LIT>' , '<STR_LIT>' , str ( self . offset ) , self . loopback , self . get_raw_path ( ) ] <EOL> if not self . read_write : <EOL> cmd . insert ( <NUM_LIT:1> , '<STR_LIT>' ) <EOL> try : <EOL> _util . check_call_ ( cmd , stdout = subprocess . PIPE ) <EOL> except Exception : <EOL> logger . exception ( "<STR_LIT>" ) <EOL> return False <EOL> try : <EOL> output = _util . check_output_ ( [ '<STR_LIT>' , '<STR_LIT>' , self . loopback ] , stderr = subprocess . STDOUT ) <EOL> match = re . findall ( r"<STR_LIT>" , output ) <EOL> if match : <EOL> self . md_device = os . path . realpath ( match [ <NUM_LIT:0> ] ) <EOL> logger . info ( "<STR_LIT>" . format ( self . md_device ) ) <EOL> except Exception as e : <EOL> logger . exception ( "<STR_LIT>" ) <EOL> return False <EOL> return True <EOL> def mount_volumes ( self , single = None , only_mount = None ) : <EOL> """<STR_LIT>""" <EOL> if os . path . isdir ( self . get_raw_path ( ) ) and self . mount_directories : <EOL> logger . info ( "<STR_LIT>" ) <EOL> for v in self . mount_directory ( only_mount ) : <EOL> yield v <EOL> elif single : <EOL> for v in self . mount_single_volume ( only_mount ) : <EOL> yield v <EOL> else : <EOL> amount = <NUM_LIT:0> <EOL> for v in self . mount_multiple_volumes ( only_mount ) : <EOL> amount += <NUM_LIT:1> <EOL> yield v <EOL> if single is None and amount == <NUM_LIT:0> : <EOL> logger . info ( "<STR_LIT>" ) <EOL> for v in self . mount_single_volume ( only_mount ) : <EOL> yield v <EOL> def mount_directory ( self , only_mount = None ) : <EOL> """<STR_LIT>""" <EOL> if not self . mount_directories : <EOL> return <EOL> volume = self . volumes . _make_single_subvolume ( ) <EOL> volume . offset = <NUM_LIT:0> <EOL> volume . flag = '<STR_LIT>' <EOL> volume . fsdescription = '<STR_LIT>' <EOL> filesize = _util . check_output_ ( [ '<STR_LIT>' , '<STR_LIT>' , self . get_fs_path ( ) ] ) . strip ( ) <EOL> if filesize : <EOL> volume . size = int ( filesize . splitlines ( ) [ - <NUM_LIT:1> ] . split ( ) [ <NUM_LIT:0> ] ) <EOL> self . volume_source = '<STR_LIT>' <EOL> for v in volume . init ( no_stats = True , only_mount = only_mount ) : <EOL> yield v <EOL> def mount_single_volume ( self , only_mount = None ) : <EOL> """<STR_LIT>""" <EOL> volume = self . volumes . _make_single_subvolume ( ) <EOL> volume . offset = <NUM_LIT:0> <EOL> description = _util . check_output_ ( [ '<STR_LIT:file>' , '<STR_LIT>' , self . get_fs_path ( ) ] ) . strip ( ) <EOL> if description : <EOL> volume . fsdescription = description . split ( '<STR_LIT>' , <NUM_LIT:1> ) [ <NUM_LIT:1> ] . split ( '<STR_LIT:U+002C>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] . strip ( ) <EOL> if '<STR_LIT:size>' in description : <EOL> volume . size = int ( re . findall ( r'<STR_LIT>' , description ) [ <NUM_LIT:0> ] ) <EOL> else : <EOL> volume . size = os . path . getsize ( self . get_fs_path ( ) ) <EOL> volume . flag = '<STR_LIT>' <EOL> self . volume_source = '<STR_LIT>' <EOL> self . volumes . _assign_disktype_data ( volume ) <EOL> for v in volume . init ( no_stats = True , only_mount = only_mount ) : <EOL> yield v <EOL> def mount_multiple_volumes ( self , only_mount = None ) : <EOL> """<STR_LIT>""" <EOL> for v in self . volumes . detect_volumes ( ) : <EOL> for w in v . init ( only_mount = only_mount ) : <EOL> yield w <EOL> def get_volumes ( self ) : <EOL> """<STR_LIT>""" <EOL> volumes = [ ] <EOL> for v in self . volumes : <EOL> volumes . extend ( v . get_volumes ( ) ) <EOL> return volumes <EOL> def rw_active ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . rwpath and os . path . getsize ( self . rwpath ) <EOL> def unmount ( self , remove_rw = False ) : <EOL> """<STR_LIT>""" <EOL> for m in list ( sorted ( self . volumes , key = lambda v : v . mountpoint or "<STR_LIT>" , reverse = True ) ) : <EOL> if not m . unmount ( ) : <EOL> logger . warning ( "<STR_LIT>" . format ( m . mountpoint ) ) <EOL> if self . md_device : <EOL> try : <EOL> _util . check_call_ ( [ '<STR_LIT>' , '<STR_LIT>' , self . md_device ] , stdout = subprocess . PIPE , stderr = subprocess . PIPE ) <EOL> self . md_device = None <EOL> except Exception as e : <EOL> logger . warning ( "<STR_LIT>" . format ( self . md_device ) , exc_info = True ) <EOL> if self . loopback : <EOL> try : <EOL> _util . check_call_ ( [ '<STR_LIT>' , '<STR_LIT>' , self . loopback ] ) <EOL> self . loopback = None <EOL> except Exception : <EOL> logger . warning ( "<STR_LIT>" . format ( self . loopback ) , exc_info = True ) <EOL> if self . mountpoint and not _util . clean_unmount ( [ '<STR_LIT>' , '<STR_LIT>' ] , self . mountpoint ) : <EOL> logger . error ( "<STR_LIT>" . format ( self . mountpoint ) ) <EOL> return False <EOL> if self . avfs_mountpoint and not _util . clean_unmount ( [ '<STR_LIT>' , '<STR_LIT>' ] , self . avfs_mountpoint ) : <EOL> logger . error ( "<STR_LIT>" . format ( self . avfs_mountpoint ) ) <EOL> return False <EOL> if self . rw_active ( ) and remove_rw : <EOL> os . remove ( self . rwpath ) <EOL> return True </s>
